1<?php 2/** 3 * i-net Download Plugin 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author i-net software <tools@inetsoftware.de> 7 * @author Gerry Weissbach <gweissbach@inetsoftware.de> 8 */ 9 10/* 11 * delete from tblTranslation Where Value like '%\?\?\?%' and Lang not in ('en', 'de', 'es'); 12 * DROP TABLE IF EXISTS tblTranslation_old; 13 * create table tblTranslation2 like tblTranslation; 14 * INSERT INTO tblTranslation2 (KeyID, Lang, Date, Value, User) SELECT KeyID, Lang, MAX(Date), Value, User FROM tblTranslation GROUP BY Value, Lang, KeyID, User; 15 * RENAME TABLE tblTranslation TO tblTranslation_old; 16 * RENAME TABLE tblTranslation2 TO tblTranslation; 17 */ 18 19// must be run within Dokuwiki 20if (!defined('DOKU_INC')) die(); 21if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 22 23class helper_plugin_translator extends DokuWiki_Plugin { // DokuWiki_Helper_Plugin 24 25 var $database = null; 26 var $checkedOK = null; 27 var $pageWordLenIdx = null; 28 var $revertableUpload = array(); 29 30 var $dataBaseStruct = array ( 31 "tblCategory" => array( 'statement' => "CREATE TABLE `tblCategory` ( 32 `CategoryID` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY, 33 `Name` VARCHAR( 255 ) NOT NULL , 34 `FileName` VARCHAR( 255 ) NOT NULL 35 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci;", 36 'fields' => array('CategoryID', 'Name', 'FileName') 37 ), 38 "tblMasterKey" => array( 'statement' => "CREATE TABLE `tblMasterKey` ( 39 `KeyID` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , 40 `ResourceKey` VARCHAR( 255 ) NOT NULL , 41 `Value` TEXT NOT NULL , 42 `MD5KeyVal` VARCHAR( 255 ) NOT NULL , 43 UNIQUE ( `Md5KeyVal` ) 44 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci;", 45 'fields' => array('KeyID', 'ResourceKey', 'Value', 'MD5KeyVal') 46 ), 47 "tblMaster" => array( 'statement' => "CREATE TABLE `tblMaster` ( 48 `KeyID` INT( 11 ) NOT NULL, 49 `CategoryID` INT( 11 ) NOT NULL, 50 `Version` VARCHAR( 255 ) NOT NULL , 51 PRIMARY KEY ( `KeyID`, `CategoryID`, `Version` ) 52 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci;", 53 'fields' => array('KeyID', 'CategoryID', 'Version') 54 ), 55 "tblTranslation" => array( 'statement' => "CREATE TABLE `tblTranslation` ( 56 `KeyID` VARCHAR( 255 ) NOT NULL , 57 `Lang` VARCHAR( 10 ) NOT NULL , 58 `Date` DATETIME NOT NULL , 59 `Value` TEXT NOT NULL , 60 `User` VARCHAR( 255 ) NOT NULL , 61 PRIMARY KEY ( `KeyID` , `Lang` , `Date` ) 62 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci;", 63 'fields' => array('KeyID', 'Lang', 'Value', 'User', 'Date') 64 ), 65 "tblUserRights" => array( 'statement' => "CREATE TABLE `tblUserRights` ( 66 `User` VARCHAR( 255 ) NOT NULL , 67 `Lang` VARCHAR( 255 ) NOT NULL , 68 PRIMARY KEY ( `User` ) 69 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci;", 70 'fields' => array('User', 'Lang') 71 ), 72 ); 73 74 function getInfo(){ 75 return array_merge(confToHash(dirname(__FILE__).'/info.txt'), array( 76 'name' => 'Translator - Helper', 77 )); 78 } 79 80 function getMethods() { 81 $result = array(); 82 return $result; 83 } 84 85 function checkDatabase() { 86 87 if ( $this->init_database() === false ) { 88 print "Cannot init."; 89 return false; 90 } 91 92 if ( empty($this->database) ) { 93 print $this->lang['nodatabase']; 94 return false; 95 } 96 97 if ( !is_null($this->checkedOK) ) { return $this->checkedOK; } 98 $this->checkedOK = $this->currentVersionChecked(); 99 if ( $this->checkedOK ) { return $this->checkedOK; } 100 101 foreach ($this->dataBaseStruct as $tableName => $sqlStatement ) { 102 103 $this->database->query("SHOW TABLES LIKE \"$tableName\";"); 104 //$this->database->execute($tableName); 105 $allGood = false; 106 107 if ( $this->database->num_rows() != 1 ) { 108 msg("Creating table '$tableName'", 0); 109 $this->database->prepare($sqlStatement['statement']); 110 $this->database->execute(); 111 $allGood = true; 112 } else { 113 // Check Log 114 $table = $this->database->databaseConnection->escape_string($tableName); 115 $this->database->prepare("SHOW COLUMNS FROM `$table`"); 116 $this->database->execute(); 117 118 if ( $this->database->num_rows() >= count($sqlStatement['fields']) ) { 119 120 $allGood = true; 121 $data = array(); $this->database->bind_assoc($data); 122 while ( $this->database->fetch() ) { 123 if ( !in_array($data['Field'], $sqlStatement['fields']) ) { 124 msg("Field missing in '$tableName': '{$data['Field']}'", -1); 125 $allGood = false; 126 break; 127 } 128 } 129 } 130 } 131 } 132 133 $this->checkedOK = $allGood; 134 if ( $allGood ) { 135 $this->setCurrentVersionChecked(); 136 } 137 138 return $allGood; 139 } 140 141 142 function init_database() { 143 144 if ( empty($this->database) ) { 145 if ( !$this->database =& plugin_load('helper', 'databaseconnector', true) ) { return false;} 146 $this->dbType = $dbType; 147 $this->database->setType($this->getConf('DBType')); 148 if ( $this->database->connect($this->getConf('DBName'), $this->getConf('DBUserName'), $this->getConf('DBUserPassword'), $this->getConf('DBHostName')) ) { 149 return true; 150 } 151 return false; 152 } 153 } 154 155 function close_database() { 156 157 if ( !empty($this->database) ) { 158 $this->database->close(); 159 $this->database = null; 160 } 161 } 162 163 function _hashKey($key, $value) { 164 return md5($key . $value); 165 } 166 167 /* 168 * Create Master Key / Value Entries 169 */ 170 function _createMasterTableEntry($translation, $categoryID, $version, &$finalStatus) { 171 172 foreach ( $translation as $key => $value) { 173 174 $KeyID = null; 175 $HASHKEY = $this->_hashKey($key, $value); 176 177 // Check if Key => Value is in tblMasterKeys 178 $this->database->prepare("SELECT KeyID FROM tblMasterKey WHERE MD5KeyVal=?;"); 179 $this->database->execute($HASHKEY); 180 181 if ( $this->database->num_rows() == 0 ) { 182 183 // Key is not in DB ... is there a Key with another value for the current Category? Order DESC by Version 184 $this->database->prepare("SELECT tblMasterKey.KeyID FROM tblMaster LEFT JOIN tblMasterKey ON tblMaster.KeyID=tblMasterKey.KeyID WHERE ResourceKey=? AND CategoryID=? ORDER BY Version DESC;"); 185 $this->database->execute($key, $categoryID); 186 if ( $this->database->num_rows() > 0 ) { 187 $data = array(); $this->database->bind_assoc($data); $this->database->fetch(); 188 $KeyID = $data['KeyID']; 189 190 // Update Database 191 $this->database->prepare("UPDATE tblMasterKey SET Value=?, Md5KeyVal=? WHERE KeyID=?;"); 192 $this->database->execute($value, $HASHKEY, $KeyID); 193 } else { 194 // The Key is not in the Database, so add it 195 $this->database->prepare("INSERT INTO tblMasterKey (ResourceKey, Value, Md5KeyVal) VALUES(?, ?, ?);"); 196 $this->database->execute($key, $value, $HASHKEY); 197 $KeyID = $this->database->insert_id(); 198 } 199 } else { 200 // Fetch inserted Key ID 201 $data = array(); $this->database->bind_assoc($data); $this->database->fetch(); 202 $KeyID = $data['KeyID']; 203 204 // If exists with same Version Return 205 $this->database->prepare("SELECT KeyID FROM tblMaster WHERE KeyID=? AND CategoryID=? AND Version=?;"); 206 $this->database->execute($KeyID, $categoryID, $version); 207 if ( $this->database->num_rows() > 0 ) { 208 $finalStatus['KeysMatchingExisting']++; 209 continue; 210 } 211 } 212 213 // Add KeyID to tblMaster 214 $this->database->prepare("INSERT INTO tblMaster (KeyID, CategoryID, Version) VALUES(?, ?, ?);"); 215 $this->database->execute($KeyID, $categoryID, $version); 216 continue; 217 } 218 } 219 220 /* 221 * get Category ID via Name 222 */ 223 function _getCategoryFromName($categoryName) { 224 225 $CATEGORIES = $this->_getCategories($categoryName); 226 if ( empty($CATEGORIES[$categoryName]) ) { 227 msg($this->_messageReplacer('CategoryNotFound', $categoryName), -1); 228 return false; 229 } 230 231 return array( $CATEGORIES[$categoryName]['CategoryID'], str_replace('[LANG]', '(.*?)', $CATEGORIES[$categoryName]['FileName'])); 232 } 233 234 /* 235 * get Categories 236 */ 237 function _getCategories($categoryName=null, $isID=false) { 238 239 $additional = ''; $execute = array(); $return = array(); 240 if ( !empty($categoryName) ) { 241 if ( $isID ) { 242 $additional .= "WHERE CategoryID=?"; 243 } else { 244 $additional .= "WHERE Name=?"; 245 } 246 247 $execute[] = $categoryName; 248 } 249 250 $this->database->prepare("SELECT Name, CategoryID, FileName FROM tblCategory $additional;"); 251 $this->database->execute($execute); 252 253 if ( $this->database->num_rows() == 0 ) { 254 return $return; 255 } 256 257 $data = array(); $this->database->bind_assoc($data); 258 while ( $this->database->fetch() ) { 259 $return[$data['Name']] = array( 'CategoryID' => $data['CategoryID'], 260 'FileName' => $data['FileName'], 261 ); 262 } 263 264 return $return; 265 } 266 267 /* 268 * Get Available Languages for a Category 269 */ 270 function _getAvailableLanguagesVersions($categoryID) { 271 272 if ( !$categoryID ) { 273 return; 274 } 275 276 $SQL = "Select DISTINCT Version, Lang FROM (SELECT Version, keyID FROM tblMaster WHERE CategoryID=? GROUP BY Version) as t1 INNER JOIN tblTranslation ON t1.KeyID = tblTranslation.KeyID"; 277 $SQL = "SELECT Version, Lang FROM tblTranslation INNER JOIN tblMaster ON tblMaster.KeyID=tblTranslation.KeyID WHERE CategoryID=? GROUP BY Version, Lang;"; 278 279 // Approximativ - vermutlich zu viel, aber besser als gar nix! 280 $SQL = "SELECT Lang, Version FROM (SELECT DISTINCT Lang FROM tblTranslation) as t1 CROSS JOIN (SELECT DISTINCT Version FROM tblMaster WHERE CategoryID=?) as t2;"; 281 282 $this->database->prepare($SQL); 283 $this->database->execute($categoryID); 284 285 $languages = array(); $data = array(); $this->database->bind_assoc($data); 286 while ( $this->database->fetch() ) { 287 $languages[$data['Version']][] = $data['Lang']; 288 } 289 290 foreach ( array_keys($languages) as $key ) { 291 array_unshift($languages[$key], $this->getConf('default_language')); 292 } 293 294 return $languages; 295 } 296 297 298 /* 299 * Get Available Languages for a Category 300 */ 301 function _getAvailableLanguages($categoryID, $version=null) { 302 303 $EXECUTE = array($categoryID); 304 if ( !empty($version) ) { 305 $ADDITIONAL .= " AND Version=?"; 306 $EXECUTE[] = $version; 307 } 308 309 $languages = array($this->getConf('default_language')); 310 $this->database->prepare("SELECT Lang FROM tblTranslation INNER JOIN tblMaster ON tblMaster.KeyID=tblTranslation.KeyID WHERE CategoryID=? $ADDITIONAL GROUP BY Lang;"); 311 $this->database->execute($EXECUTE); 312 313 $data = array(); $this->database->bind_assoc($data); 314 while ( $this->database->fetch() ) { 315 $languages[] = $data['Lang']; 316 } 317 318 return $languages; 319 } 320 321 /* 322 * Get Available Versions for a Category 323 */ 324 function _getAvailableVersions($categoryID=null) { 325 326 $EXECUTE = array(); 327 $ADDITIONAL = ""; 328 if ( !empty( $categoryID) ) { 329 $EXECUTE[] = $categoryID; 330 $ADDITIONAL .= " WHERE CategoryID=? "; 331 } 332 333 $versions = array(); 334 $this->database->prepare("SELECT Version FROM tblMaster $ADDITIONAL GROUP BY Version;"); 335 $this->database->execute($EXECUTE); 336 337 $data = array(); $this->database->bind_assoc($data); 338 while ( $this->database->fetch() ) { 339 $versions[] = trim($data['Version']); 340 } 341 342 $versions = array_unique($versions); 343 usort($versions, array($this, "_sortVersion")); 344 345 return $versions; 346 } 347 348 function _sortVersion($a, $b) { 349 350 if ($a === $b ) { 351 return 0; 352 } else if ( is_numeric($a) && is_numeric($b) ) { 353 return $a < $b ? -1 : 1; 354 } else if ( !is_numeric($a) && !is_numeric($b) ) { 355 return strcmp($a, $b); 356 } else if ( !is_numeric($a)) { 357 return 1; 358 } else { 359 return -1; 360 } 361 } 362 363 /* 364 * Get Key from Master via Name 365 */ 366 function _getMasterKeyIDFromName($KeyName, $CategoryID, $isID=false, $getID=true) { 367 368 $this->setUTF8Collation(); 369 370 $WHATTO = 'tblMasterKey.ResourceKey'; 371 if ( $isID ) { 372 $WHATTO = 'tblMasterKey.KeyID'; 373 } 374 375 // Get latest MasterKeyID from Category 376 $this->database->prepare("SELECT DISTINCT tblMasterKey.KeyID, Value FROM tblMasterKey INNER JOIN tblMaster ON tblMasterKey.KeyID=tblMaster.KeyID WHERE tblMaster.CategoryID=? AND $WHATTO=? ORDER BY Version DESC;"); 377 $this->database->execute($CategoryID, $KeyName); 378 379 if ( $this->database->num_rows() > 0 ) { 380 $data = array(); $this->database->bind_assoc($data); $this->database->fetch(); 381 return $getID ? $data['KeyID'] : $data['Value']; 382 } else { 383 return false; 384 } 385 } 386 387 /** 388 * Check for all Keys if they do have a master - otherwise, kick them 389 * @param $translation 390 * @param $finalStatus 391 * @param $CategoryID 392 */ 393 function _checkForMasterKeyIDs(&$translation, &$finalStatus, $CategoryID) { 394 395 $this->setUTF8Collation(); 396 397 $keysIN = implode("\",\"", array_keys($translation)); 398 // $keysIN = str_replace("(", "\(", $keysIN); 399 // $keysIN = str_replace(")", "\)", $keysIN); 400 401 // Get latest MasterKeyID from Category 402 $SQL = "SELECT DISTINCT tblMasterKey.KeyID, tblMasterKey.ResourceKey FROM tblMasterKey INNER JOIN tblMaster ON tblMasterKey.KeyID=tblMaster.KeyID WHERE tblMaster.CategoryID=? AND tblMasterKey.ResourceKey in ( \"$keysIN\" ) ORDER BY Version DESC;"; 403 $this->database->prepare($SQL); 404 $this->database->execute($CategoryID); 405 406 $data = array(); $this->database->bind_assoc($data); 407 while ( $this->database->fetch() ) { 408 $translation[$data['ResourceKey']] = array( 'ID' => $data['KeyID'], 'Value' => $translation[$data['ResourceKey']] ); 409 $finalStatus['CountOfKeys']++; 410 } 411 } 412 413 /* 414 * Check if a key exists - additionally check for Lang and Value 415 */ 416 function _keyExists($KeyID, $Lang=null, $Value=null, $Date=null) { 417 418 $additional = ""; 419 $execute = array( $KeyID ); 420 421 if ( !empty($Lang) ) { 422 $additional .= " AND Lang=?"; 423 $execute[] = $Lang; 424 } 425 426 if ( !empty($Date) ) { 427 $additional .= " AND Date=?"; 428 $execute[] = $Date; 429 } 430 431 $SQL = "SELECT KeyID, Value FROM tblTranslation WHERE KeyID=? $additional"; 432 433 // Checks for the latest Entry 434 if ( !empty($Value) ) { 435 $SQL = "SELECT tblTrans.KeyID FROM ($SQL ORDER BY Date DESC LIMIT 1) as tblTrans WHERE BINARY tblTrans.Value=?"; 436 $execute[] = $Value; 437 } 438 439 $this->database->prepare("$SQL;"); 440 $this->database->execute($execute); 441 442 if ( $this->database->num_rows() == 0 ) { 443 return false; 444 } 445 446 return true; 447 } 448 449 /* 450 * Insert a new Translation Set of Translations 451 */ 452 function _insertTranslation($KeyID, $Value, $Lang, $Date, $User=null) { 453 global $INFO; 454 455 $revertable = false; 456 457 if ( empty($Value) ) return $revertable; 458 459 // Bottleneck 2 460 if ( $this->_keyExists($KeyID, $Lang) ) { 461 462 if ( $this->_keyExists($KeyID, $Lang, $Value) || $this->_keyExists($KeyID, $Lang, null, $Date) ) { 463 return -1; 464 } 465 466 $revertable = true; 467 } 468 469 // Insert Translation 470 if ( empty($User) ) $User = $_SERVER['REMOTE_USER']; 471 472 473 $this->database->prepare("INSERT INTO tblTranslation (KeyID, Lang, Value, User, Date) VALUES(?, ?, ?, ?, ?);"); 474 $this->database->execute($KeyID, $Lang, $Value, $User, $Date); 475 476 return $revertable; 477 } 478 479 function _insertTranslationArray($translation, &$finalStatus, $Lang, $Date) { 480 481 $CHECK = ''; 482 $translationINV = array(); 483 foreach( $translation as $key => $value ) { 484 if ( !is_array($value) ) { 485 $finalStatus['KeysNotInMaster'][] = $key; 486 unset($translation[$key]); 487 continue; 488 } 489 490 $CHECK .= $value['ID'] . ","; 491 $translationINV[$value['ID']] = array( 492 'key' => $key, 493 'value' => $value['Value'] 494 ); 495 } 496 497 $CHECK = substr($CHECK, 0, -1); 498 $SQL = "SELECT DISTINCT * FROM (SELECT KeyID, Value, Date FROM tblTranslation WHERE KeyID in ( $CHECK ) AND Lang=? ORDER BY Date) as t1 GROUP BY KeyID;"; 499 500 $this->database->prepare($SQL); 501 $this->database->execute($Lang); 502 503 $data = array(); $this->database->bind_assoc($data); 504 while ( $this->database->fetch() ) { 505 506 if ( $translationINV[$data['KeyID']]['value'] == $data['Value'] || $data['Date'] == $Date ) { 507 $finalStatus['KeysMatchingExisting'][] = $translationINV[$data['KeyID']]['key']; 508 unset( $translation[$translationINV[$data['KeyID']]['key']] ); 509 unset( $translationINV[$data['KeyID']] ); 510 continue; 511 } 512 513 $finalStatus['CountOfToBeReverted']++; 514 } 515 unset($SQL); 516 517 if ( empty($translation) ) { 518 return; 519 } 520 521 $INSERT = ''; 522 $INSERTDATA = array(); 523 foreach( $translation as $key => $value ) { 524 525 $INSERTDATA[] = $value['ID']; 526 $INSERTDATA[] = $Lang; 527 $INSERTDATA[] = $value['value']; 528 $INSERTDATA[] = $_SERVER['REMOTE_USER']; 529 $INSERTDATA[] = $Date; 530 531 $INSERT .= '(?,?,?,?,?),'; 532 } 533 534 $INSERT = substr($INSERT, 0, -1); 535 $this->database->prepare("INSERT INTO tblTranslation (KeyID, Lang, Value, User, Date) VALUES $INSERT;"); 536 $this->database->execute($INSERTDATA); 537 } 538 539 540 function _getTranslation($CategoryID, $Version, $Language) { 541 542 $this->setUTF8Collation(); 543 544 if ( $Language == $this->getConf('default_language') ) { 545 $this->database->prepare("SELECT ResourceKey, Value FROM tblMasterKey INNER JOIN tblMaster ON tblMasterKey.KeyID=tblMaster.KeyID WHERE tblMaster.Version=? AND tblMaster.CategoryID=? ORDER BY tblMasterKey.ResourceKey;"); 546 $this->database->execute($Version, $CategoryID); 547 } else { 548 $this->database->prepare("SELECT tblMasterKey.ResourceKey, tblTrans.Value FROM (tblMasterKey INNER JOIN tblMaster ON tblMasterKey.KeyID=tblMaster.KeyID AND tblMaster.Version=? AND tblMaster.CategoryID=?) INNER JOIN (SELECT * FROM (SELECT * FROM tblTranslation WHERE tblTranslation.Lang=? ORDER BY tblTranslation.Date DESC) as tblTemp1 GROUP BY KeyID) as tblTrans ON tblMasterKey.KeyID = tblTrans.KeyID ORDER BY ResourceKey, Value;"); 549 $this->database->execute($Version, $CategoryID, $Language); 550 } 551 552 $return = array(); 553 $data = array(); $this->database->bind_assoc($data); 554 while ( $this->database->fetch() ) { 555 $return[$data['ResourceKey']] = $data['Value']; 556 } 557 558 return $return; 559 } 560 561 /* 562 * Revert Entries by dateTime, lang and user 563 */ 564 function _revertEntries($dateTime, $lang, $user=null) { 565 global $INFO; 566 567 if ( empty($user) ) $user = $_SERVER['REMOTE_USER']; 568 $this->database->prepare("DELETE FROM tblTranslation WHERE Date=? AND Lang=? AND User=?;"); 569 $this->database->execute($dateTime, $lang, $user); 570 571 return $this->database->num_rows(); 572 } 573 574 /* ****************************************************************************************************************************** 575 * Export Manager 576 ***************************************************************************************************************************** */ 577 function _exportManager($caller) { 578 579 $form = $caller->_startFieldSet($this->getLang('ExportManager'), 'translator_export'); 580 581 list($categories, $changeCategory, $changeVersion) = $this->_getChangerJS(); 582 583 $versions = array(); 584 $languages = array(); 585 586 if ( is_array($categories[$_REQUEST['Category']]['Versions']) ) { 587 $versions = array_keys($categories[$_REQUEST['Category']]['Versions']); 588 } 589 590 if ( is_array($categories[$_REQUEST['Category']]['Versions'][$_REQUEST['Version']]) ) { 591 $languages = array_values($categories[$_REQUEST['Category']]['Versions'][$_REQUEST['Version']]); 592 } 593 594 $form->addElement(form_makeListboxField('Category', array_keys($categories), $_REQUEST['Category'], $this->getLang('Category') . ':', null, null, array('onchange' => $changeCategory))); 595 $form->addElement(form_makeTag('br')); 596 $form->addElement(form_makeListboxField('Version', $versions, $_REQUEST['Version'], $this->getLang('Version') . ':', null, null, array('onchange' => $changeVersion))); 597 $form->addElement(form_makeTag('br')); 598 $form->addElement(form_makeListboxField('Language', $languages, $_REQUEST['Language'], $this->getLang('Language') . ':')); 599 $form->addElement(form_makeTag('br')); 600 $form->addElement(form_makeField('submit', 'export_language', $this->getLang('Export'), '')); 601 602 $caller->_finishFieldset($form); 603 } 604 605 /** 606 * Set headers and send the file to the client 607 */ 608 function _sendLanguageFile($data, $fileName){ 609 global $conf; 610 611 // send headers 612 header("Content-Type: text"); 613 // nocache 614 header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0'); 615 header('Pragma: public'); 616 header('Content-Disposition: attachment; filename="'.$fileName.'";'); 617 618 // send file contents 619 if ( !empty($data) ) { 620 foreach( $data as $line ) { 621 print "$line\r\n"; flush(); 622 } 623 } 624 } 625 626 function capture_form_output($form) { 627 628 if ( !$form ) { return ''; } 629 ob_start(); 630 $form->printForm(); 631 $output = ob_get_contents(); 632 ob_end_clean(); 633 634 return trim($output); 635 } 636 637 function _getTranslationMatrix($category, $Version, $Language, $additionalLanguage=null, $start="0", $amount="50", $display=null, $filter=null) { 638 639 $this->setUTF8Collation(); 640 641 if ( empty($display) ) { 642 $display = $this->getLang('notTranslated'); 643 } 644 645 $matrix = array(); 646 list($categoryID) = $this->_getCategoryFromName($category); 647 648 if ( $additionalLanguage == $this->getConf('default_language') ) $additionalLanguage = null; 649 650 $ADDITIONAL = ""; 651 $ADDITIONALKEYS = ""; 652 653 $EXECUTE = array($categoryID, $Version, $Language, $Language); 654 655 // add SQL for Additional Language 656 if ( !empty($additionalLanguage) ) { 657 $ADDITIONAL .= "LEFT JOIN ( tblTranslation as AdditionalTranslation INNER JOIN 658 (SELECT KeyID, MAX(Date) AS Date FROM tblTranslation WHERE Lang=? GROUP BY KeyID) as tblOldestAddTrans ON 659 tblOldestAddTrans.KeyID=AdditionalTranslation.KeyID AND tblOldestAddTrans.Date=AdditionalTranslation.Date AND AdditionalTranslation.Lang=?) ON 660 tblMaster.KeyID = AdditionalTranslation.KeyID "; 661 662 $ADDITIONALKEYS .= ", AdditionalTranslation.Value as AdditionalValue"; 663 array_push($EXECUTE, $additionalLanguage); 664 array_push($EXECUTE, $additionalLanguage); 665 } 666 667 // Modify Display settings 668 switch($display) { 669 case $this->getLang('notTranslated') : $ADDITIONAL .= "WHERE tblTranslation.Value IS NULL"; 670 break; 671 case $this->getLang('translated') : $ADDITIONAL .= "WHERE tblTranslation.Value IS NOT NULL"; 672 break; 673 } 674 675 // Add Filter 676 if ( !empty($filter) ) { 677 if ( !strstr($ADDITIONAL, 'WHERE')) { 678 $ADDITIONAL .= "WHERE"; 679 } else { 680 $ADDITIONAL .= " AND"; 681 } 682 683 if( substr($filter, 0, 1) != "%" ) $filter = "%" . $filter; 684 if( substr($filter, -1) != "%" ) $filter .= "%"; 685 686 $ADDITIONAL .= ' (ResourceKey LIKE ? OR tblMasterKey.Value LIKE ? OR tblTranslation.Value LIKE ?'; 687 if ( !empty($additionalLanguage) ) { 688 $ADDITIONAL .= ' OR AdditionalTranslation.Value LIKE ? '; 689 array_push($EXECUTE, $filter); 690 } 691 692 $ADDITIONAL .= ')'; 693 694 array_push($EXECUTE, $filter); 695 array_push($EXECUTE, $filter); 696 array_push($EXECUTE, $filter); 697 } 698 699 if ( empty($amount) ) $amount = 50; 700 // Limits 701 702 // Build SQL 703 704 $SQL = "SELECT tblMasterKey.KeyID, ResourceKey, tblMasterKey.Value as MasterValue, 705 tblTranslation.Value as TranslationValue, tblTranslation.User $ADDITIONALKEYS 706 FROM ( 707 ( tblMasterKey INNER JOIN tblMaster ON 708 tblMaster.KeyID = tblMasterKey.KeyID AND CategoryID = ? AND Version = ? ) 709 710 LEFT JOIN ( 711 tblTranslation INNER JOIN 712 (SELECT KeyID, MAX(Date) AS Date FROM tblTranslation WHERE Lang=? GROUP BY KeyID) as tblOldestTrans ON 713 tblOldestTrans.KeyID=tblTranslation.KeyID AND tblOldestTrans.Date=tblTranslation.Date 714 ) ON tblMaster.KeyID = tblTranslation.KeyID AND Lang=? 715 ) $ADDITIONAL ORDER BY tblMaster.KeyID LIMIT ? OFFSET ?;"; 716 717 $this->database->prepare("$SQL"); 718 $this->database->execute(array_merge($EXECUTE, array('1000000000000', '0'))); 719 $max = $this->database->num_rows(); 720 721 array_push($EXECUTE, intval($amount)); 722 array_push($EXECUTE, intval($start)); 723 724 // Fetch Data 725 $this->database->execute($EXECUTE); 726 727 if ( $this->database->num_rows() == 0 ) { 728 return false; 729 } 730 731 $data = array(); $this->database->bind_assoc($data); 732 while ( $this->database->fetch() ) { 733 734 $matrix[$data['KeyID']] = array ( 735 'KeyID' => $data['KeyID'], 736 'ResourceKey' => $data['ResourceKey'], 737 'MasterValue' => str_replace('\n', "\r\n", $this->_stringDecode($data['MasterValue'])), 738 'TranslationValue' => str_replace('\n', "\r\n", $this->_stringDecode($data['TranslationValue'])), 739 'AdditionalValue' => str_replace('\n', "\r\n", $this->_stringDecode($data['AdditionalValue'])), 740 'User' => $data['User'], 741 ); 742 } 743 744 return array($matrix, $max); 745 } 746 747 748 /* 749 * get the users languages from the database and return false if none are there 750 */ 751 function _getLanguages() { 752 global $INFO; 753 754 // print_r($INFO); 755 // print $_SERVER['REMOTE_USER']; 756 757 if ( empty($INFO['userinfo']) ) { 758 return false; 759 } 760 761 $this->database->prepare("SELECT Lang FROM tblUserRights WHERE User=?"); 762 $this->database->execute($_SERVER['REMOTE_USER']); 763 764 if ( $this->database->num_rows() == 0) { 765 return false; 766 } 767 768 $data = array(); $this->database->bind_assoc($data); $this->database->fetch(); 769 return trim($data['Lang']); 770 } 771 772 function _handleRequest($fn) { 773 if (is_array($fn)) { 774 $cmd = key($fn); 775 $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null; 776 } else { 777 $cmd = $fn; 778 $param = null; 779 } 780 781 switch($cmd){ 782 case "revertuploaded" : $this->_revertUploadedEntries($_REQUEST['revert']); break; 783 case "translate" : $this->_updateTranslation($_REQUEST['Language'], $_REQUEST['translation']); break; 784 case "setpage" : $_REQUEST['start'] = $param; $_REQUEST['amount'] = $_REQUEST['newAmount']; $_REQUEST['AdditionalLanguage'] = $_REQUEST['newAdditionalLanguage']; break; 785 case "setup" : $_REQUEST['Language'] = $param; $_REQUEST['Display'] = $param ? key($fn[$cmd][$param]) : null; break; 786 } 787 } 788 789 790 function _stringEncode($var) { 791 792 // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT 793 $ascii = ''; 794 //$var = str_replace("\n", '\n', $var); 795 $strlen_var = strlen($var); 796 797 /* 798 * Iterate over every character in the string, 799 * escaping with a slash or encoding to UTF-8 where necessary 800 */ 801 for ($c = 0; $c < $strlen_var; ++$c) { 802 803 $ord_var_c = ord($var{$c}); 804 805 switch ($ord_var_c) { 806 case 0x08: $ascii .= '\b'; break; 807 case 0x09: $ascii .= '\t'; break; 808 case 0x0A: $ascii .= '\n'; break; 809 case 0x0C: $ascii .= '\f'; break; 810 case 0x0D: $ascii .= '\r'; break; 811 case 0x3D: $ascii .= '\='; break; 812 case 0x3A: $ascii .= '\:'; break; 813 814 case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): 815 // characters U-00000000 - U-0000007F (same as ASCII) 816 $ascii .= $var{$c}; 817 break; 818 819 case (($ord_var_c & 0xE0) == 0xC0): 820 // characters U-00000080 - U-000007FF, mask 110XXXXX 821 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 822 $char = pack('C*', $ord_var_c, ord($var{$c+1})); 823 $c+=1; 824 //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8'); 825 $utf16 = utf8_to_utf16be($char); 826 $ascii .= sprintf('\u%04s', strtoupper(bin2hex($utf16))); 827 break; 828 829 case (($ord_var_c & 0xF0) == 0xE0): 830 // characters U-00000800 - U-0000FFFF, mask 1110XXXX 831 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 832 $char = pack('C*', $ord_var_c, 833 ord($var{$c+1}), 834 ord($var{$c+2})); 835 $c+=2; 836 //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8'); 837 $utf16 = utf8_to_utf16be($char); 838 $ascii .= sprintf('\u%04s', strtoupper(bin2hex($utf16))); 839 break; 840 841 case (($ord_var_c & 0xF8) == 0xF0): 842 // characters U-00010000 - U-001FFFFF, mask 11110XXX 843 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 844 $char = pack('C*', $ord_var_c, 845 ord($var{$c+1}), 846 ord($var{$c+2}), 847 ord($var{$c+3})); 848 $c+=3; 849 //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8'); 850 $utf16 = utf8_to_utf16be($char); 851 $ascii .= sprintf('\u%04s', strtoupper(bin2hex($utf16))); 852 break; 853 854 case (($ord_var_c & 0xFC) == 0xF8): 855 // characters U-00200000 - U-03FFFFFF, mask 111110XX 856 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 857 $char = pack('C*', $ord_var_c, 858 ord($var{$c+1}), 859 ord($var{$c+2}), 860 ord($var{$c+3}), 861 ord($var{$c+4})); 862 $c+=4; 863 //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8'); 864 $utf16 = utf8_to_utf16be($char); 865 $ascii .= sprintf('\u%04s', strtoupper(bin2hex($utf16))); 866 break; 867 868 case (($ord_var_c & 0xFE) == 0xFC): 869 // characters U-04000000 - U-7FFFFFFF, mask 1111110X 870 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 871 $char = pack('C*', $ord_var_c, 872 ord($var{$c+1}), 873 ord($var{$c+2}), 874 ord($var{$c+3}), 875 ord($var{$c+4}), 876 ord($var{$c+5})); 877 $c+=5; 878 //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8'); 879 $utf16 = utf8_to_utf16be($char); 880 $ascii .= sprintf('\u%04s', strtoupper(bin2hex($utf16))); 881 break; 882 } 883 } 884 885 return $ascii; 886 } 887 888 function _stringDecode($chrs) { 889 890 // STRINGS RETURNED IN UTF-8 FORMAT 891 892 $utf8 = ''; 893 $chrs = addcslashes(trim($chrs), "\n\t\r"); // Ensure to have the Line Breaks intact 894 $strlen_chrs = strlen($chrs); 895 896 for ($c = 0; $c < $strlen_chrs; ++$c) { 897 898 $substr_chrs_c_2 = substr($chrs, $c, 2); 899 $ord_chrs_c = ord($chrs{$c}); 900 901 switch ($substr_chrs_c_2) { 902 case '\b': $utf8 .= chr(0x08); $c+=1; break; 903 case '\t': $utf8 .= chr(0x09); $c+=1; break; 904 case '\n': $utf8 .= chr(0x0A); $c+=1; break; 905 case '\f': $utf8 .= chr(0x0C); $c+=1; break; 906 case '\r': $utf8 .= chr(0x0D); $c+=1; break; 907 case '\:': $utf8 .= chr(0x3A); $c+=1; break; 908 case '\=': $utf8 .= chr(0x3D); $c+=1; break; 909 910 default: 911 if (preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))) { 912 // single, escaped unicode character 913 $utf16 = chr(hexdec(substr($chrs, ($c+2), 2))) . chr(hexdec(substr($chrs, ($c+4), 2))); 914 915 //$utf8 .= mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); // This is correct for rusians 916 $utf8 .= utf16be_to_utf8($utf16); // this as Well; 917 918 //$utf8 .= utf8_decode(utf16be_to_utf8($utf16)); 919 $c+=5; 920 921 } elseif(($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F)) { 922 $utf8 .= $chrs{$c}; 923 924 } elseif(($ord_chrs_c & 0xE0) == 0xC0) { 925 // characters U-00000080 - U-000007FF, mask 110XXXXX 926 //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 927 $utf8 .= substr($chrs, $c, 2); $c += 1; 928 929 } elseif(($ord_chrs_c & 0xF0) == 0xE0) { 930 // characters U-00000800 - U-0000FFFF, mask 1110XXXX 931 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 932 $utf8 .= substr($chrs, $c, 3); $c += 2; 933 934 } elseif(($ord_chrs_c & 0xF8) == 0xF0) { 935 // characters U-00010000 - U-001FFFFF, mask 11110XXX 936 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 937 $utf8 .= substr($chrs, $c, 4); $c += 3; 938 939 } elseif(($ord_chrs_c & 0xFC) == 0xF8) { 940 // characters U-00200000 - U-03FFFFFF, mask 111110XX 941 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 942 $utf8 .= substr($chrs, $c, 5); $c += 4; 943 944 } elseif(($ord_chrs_c & 0xFE) == 0xFC) { 945 // characters U-04000000 - U-7FFFFFFF, mask 1111110X 946 // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 947 $utf8 .= substr($chrs, $c, 6); $c += 5; 948 } else { 949 // Falls doch noch andere UTF8 Zeichen enthalten sind, m�ssen die extra behandelt werden. 950 $utf8 .= chr($ord_chrs_c); 951 } 952 break; 953 } 954 955 } 956 957 // print " '$utf8' "; 958 959 return $utf8; 960 } 961 962 function _revertManager($parent, $revertableUpload) { 963 964 // If there is nothing revertable then end here; 965 if ( count($revertableUpload) == 0 ) { 966 return; 967 } 968 969 $form = $parent->_startFieldSet($this->getLang('RevertManager'), 'translator_revert'); 970 971 if ( count($revertableUpload) > 1 ) { 972 foreach ( $revertableUpload as $revertable ) { 973 $form->addElement(form_makeCheckboxField("revert[{$revertable['current_date_time']}][{$revertable['lang']}]", 1, $revertable['name'] . " ({$revertable['lang']})", null)); 974 $form->addElement(form_makeTag('br')); 975 } 976 } else { 977 $form->addElement($this->getLang('RevertManagerHowTo')); 978 $revertable = array_shift($revertableUpload); 979 $form->addHidden("revert[{$revertable['current_date_time']}][{$revertable['lang']}]", 1); 980 } 981 982 $form->addElement(form_makeField('submit', 'fn[revertuploaded]', $this->getLang('Revert'), '')); 983 return $parent->_finishFieldset($form); 984 } 985 986 function _updateTranslation($Language, $Translation) { 987 global $INFO; 988 989 $date = date('Y-m-d H:i:s'); 990 $this->revertableUpload = array(); 991 if ( !in_array($Language, explode('|', $this->_getLanguages()) ) ) return; 992 993 $finalStatus = array( 994 'KeysNotInMaster' => array(), 995 'KeysMatchingExisting' => array(), 996 'CountOfKeys' => 0, 997 'CountOfToBeReverted' => 0, 998 ); 999 1000 foreach( $Translation as $key => $value ) { 1001 1002 $finalStatus['CountOfKeys']++; 1003 1004 if ( empty($value) ) { 1005 $finalStatus['RemovedUserKeys'] += $this->_tryRevertEntry($Language, $_SERVER['REMOTE_USER'], $key); 1006 continue; 1007 } 1008 1009 // 18.05.2010 1010 // Entfernt, damit Russische �bersetzungen wieder funktionieren 1011 // $value = utf8_decode($value); 1012 1013 // 20.05.2010 1014 // Russisch darf nicht ... aber Detusch z.B. muss ... welche Ausnahmen gibt es noch? 1015 //if ( !in_array( $Language, array("ru", "zh_CN", "zh_TW", "ja", "ko") ) ) { 1016 // $value = utf8_decode($value); 1017 //} 1018 1019 // 06.12.2010 - �nderung der Datenbank. Es werden nur noch die codierten Werte gespeichert. 1020 $value = $this->_stringEncode($value); 1021 1022 $status = $this->_insertTranslation($key, $value, $Language, $date); 1023 if ( $status === -1 ) { 1024 $finalStatus['KeysMatchingExisting'][]=$key; 1025 } else if ( $status === true ) { 1026 $finalStatus['CountOfToBeReverted']++; 1027 } 1028 } 1029 1030 if ( $finalStatus['CountOfToBeReverted'] > 0 ) { 1031 $this->revertableUpload[$date] = array( 1032 'lang' => $Language, 1033 'name' => $_SERVER['REMOTE_USER'], 1034 'current_date_time' => $date, 1035 ); 1036 } 1037 1038 $this->_statusResult($finalStatus, $Language); 1039 return; 1040 1041 } 1042 1043 /* 1044 * Revert Uploaded Entries 1045 */ 1046 function _revertUploadedEntries($revertItems) { 1047 1048 if ( !is_array($revertItems) ) return; 1049 1050 foreach ( array_keys($revertItems) as $revertDateTime ) { 1051 foreach ( array_keys($revertItems[$revertDateTime]) as $lang ) { 1052 $items = $this->_revertEntries($revertDateTime, $lang); 1053 msg($this->_messageReplacer('RevertedItems', $items)); 1054 } 1055 } 1056 } 1057 1058 function _tryRevertEntry($language, $user, $key=null) { 1059 1060 if ( $language == $this->getConf('defaultLanguage') ) return false; 1061 1062 $ADDITIONAL = ""; 1063 $EXECUTE = array($user, $language); 1064 1065 if ( !empty( $key )) { 1066 $SQL = "SELECT tblTranslation.* FROM ((SELECT KeyID, MAX(Date) AS Date FROM tblTranslation WHERE Lang=? GROUP BY KeyID) as tblOldestAddTrans INNER JOIN tblTranslation ON tblOldestAddTrans.KeyID=tblTranslation.KeyID AND tblOldestAddTrans.Date=tblTranslation.Date) WHERE tblTranslation.KeyID=? AND tblTranslation.User=?;"; 1067 $this->database->prepare($SQL); 1068 $this->database->execute($language, $key, $user); 1069 $data = array(); $this->database->bind_assoc($data); $this->database->fetch(); 1070 $ADDITIONAL .= " AND KeyID=? AND Date=?"; 1071 $EXECUTE[] = $data['KeyID']; 1072 $EXECUTE[] = $data['Date']; 1073 } 1074 1075 $this->database->prepare("DELETE FROM tblTranslation WHERE User=? AND Lang=? $ADDITIONAL"); 1076 $this->database->execute($EXECUTE); 1077 1078 return $this->database->num_rows(); 1079 } 1080 1081 function _statusResult($finalStatus, $Lang, $FileName="User created") { 1082 1083 if ( !is_array($finalStatus['KeysNotInMaster']) ) $finalStatus['KeysNotInMaster'] = array($finalStatus['KeysNotInMaster']); 1084 if ( !is_array($finalStatus['KeysMatchingExisting']) ) $finalStatus['KeysMatchingExisting'] = array($finalStatus['KeysMatchingExisting']); 1085 1086 if ( count($finalStatus['KeysNotInMaster']) > 0 ) { 1087 msg($this->_messageReplacer('KeysNotInMaster', array(count($finalStatus['KeysNotInMaster']), count($finalStatus['KeysNotInMaster'])+$finalStatus['CountOfKeys'], $Lang, $FileName, implode(', ', $finalStatus['KeysNotInMaster']))), -1); 1088 } 1089 1090 if ( count($finalStatus['KeysMatchingExisting']) > 0 ) { 1091 msg($this->_messageReplacer('KeysMatchingExisting', array(count($finalStatus['KeysMatchingExisting']), $finalStatus['CountOfKeys'], $Lang, $FileName, implode(', ', $finalStatus['KeysMatchingExisting']))), 1); 1092 } 1093 1094 if ( $finalStatus['RemovedUserKeys'] > 0 ) { 1095 msg($this->_messageReplacer('RemovedUserKeys', array($finalStatus['RemovedUserKeys'], $finalStatus['CountOfKeys']))); 1096 } 1097 1098 if ( $finalStatus['CountOfToBeReverted'] > 0 ) { 1099 msg($this->getLang('RevertValues')); 1100 return false; 1101 } 1102 1103 if ( $finalStatus['KeysMatchingExisting'] == $finalStatus['CountOfKeys'] 1104 || ( $finalStatus['KeysMatchingExisting'] == 0 && $finalStatus['CountOfToBeReverted'] == 0 && $finalStatus['KeysNotInMaster'] == 0 ) ) { 1105 $_REQUEST['start'] += $_REQUEST['amount']; 1106 } 1107 1108 return true; 1109 } 1110 1111 function _getAmountOfMasterValues($categoryID=null, $version=null) { 1112 1113 $EXECUTE = array(); 1114 $ADDITIONAL = ''; 1115 if ( !empty($categoryID) ) { 1116 $ADDITIONAL .= "CategoryID=?"; 1117 $EXECUTE[] = $categoryID; 1118 } 1119 1120 if ( !empty($categoryID) ) { 1121 if ( !empty($ADDITIONAL) ) { 1122 $ADDITIONAL .= " AND "; 1123 } 1124 1125 $ADDITIONAL .= "Version=?"; 1126 $EXECUTE[] = $version; 1127 } 1128 1129 if ( !empty($ADDITIONAL) ) { 1130 $ADDITIONAL = " WHERE " . $ADDITIONAL; 1131 } 1132 1133 1134 $this->database->prepare("SELECT COUNT(tblMaster.KeyID) as amount FROM tblMasterKey INNER JOIN tblMaster ON tblMasterKey.KeyID=tblMaster.KeyID $ADDITIONAL;"); 1135 $this->database->execute($EXECUTE); 1136 1137 $data=array(); $this->database->bind_assoc($data); $this->database->fetch(); 1138 1139 return intval($data['amount']); 1140 } 1141 1142 function _getAmountOfLanguageValues($categoryID, $version, $lang) { 1143 1144 //$SQL = "SELECT COUNT(DISTINCT tblMaster.KeyID) as amount FROM tblMaster INNER JOIN tblTranslation ON tblMaster.KeyID=tblTranslation.KeyID WHERE Lang=? AND categoryID=? and Version=?;"; 1145 $SQL = "SELECT COUNT(DISTINCT tblMaster.KeyID) as amount FROM tblMaster INNER JOIN tblTranslation ON tblMaster.KeyID=tblTranslation.KeyID AND Lang=? WHERE categoryID=? and Version=?;"; 1146 //$SQL = "SELECT COUNT(tblMaster.KeyID) as amount FROM tblMaster INNER JOIN (SELECT KeyID FROM tblTranslation WHERE Lang=? GROUP BY KeyID) as tblTrans ON tblTrans.KeyID=tblMaster.KeyID WHERE categoryID=? and Version=?;"; 1147 1148 $this->database->prepare($SQL); 1149 $this->database->execute($lang, $categoryID, $version); 1150 1151 $data=array(); $this->database->bind_assoc($data); $this->database->fetch(); 1152 1153 return intval($data['amount']); 1154 } 1155 1156 function _downloadLink($category, $version, $language, $name, $NoEncoded=false) { 1157 global $ID; 1158 $options = array('export_language' => '1', 'Category' => $category, 'Version' => $version, 'Language' => $language); 1159 if ( $NoEncoded ) $options['NoEncode'] = 'true'; 1160 return tpl_link(wl($ID, $options),$name,null,true); 1161 } 1162 1163 function _messageReplacer($LangKey, $replacements) { 1164 if ( !is_array($replacements)) 1165 $replacements = array($replacements); 1166 1167 $language = $this->getLang($LangKey); 1168 for($i=0; $i<count($replacements); $i++) { 1169 $language = str_replace('{' . $i . '}', $replacements[$i], $language); 1170 } 1171 1172 return $language; 1173 } 1174 1175 function _getChangerJS($hasLanguageNode=true) { 1176 1177 $categories = $this->_getCategories(); 1178 $JSCategories = "var categories = {"; 1179 foreach ( $categories as $name => $category ) { 1180 1181 // Bottlenec 1 1182 $languages = $this->_getAvailableLanguagesVersions($category['CategoryID']); 1183 $versions = array_keys($languages); 1184 rsort($versions, SORT_NUMERIC); 1185 1186 if ( empty($versions) ) { continue; } 1187 1188 $JSCategories .= "'$name': {"; 1189 1190 // Bottlenec 2 1191 foreach( $versions as $version ) { 1192 $categories[$name]['Versions'][$version] = $hasLanguageNode ? array_unique(array_merge(array('export all'), $languages[$version])) : array(); 1193 $JSCategories .= "'$version':['" . implode("','", $categories[$name]['Versions'][$version]) . "']" . ( $version != end($versions) ? ',' : '' ); 1194 } 1195 1196 $JSCategories .= "}" . ( $name != end(array_keys($categories)) ? ',' : '' ); 1197 } 1198 $JSCategories .= "};"; 1199 1200 if ( empty( $_REQUEST['Category']) ) $_REQUEST['Category'] = array_shift(array_keys($categories)); 1201 if ( empty( $_REQUEST['Version']) && !empty($categories[$_REQUEST['Category']]['Versions']) ) $_REQUEST['Version'] = array_shift(array_keys($categories[$_REQUEST['Category']]['Versions'])); 1202 1203 $nodes = "var node = this.parentNode.parentNode.getElementsByTagName('select');"; 1204 $removeNodes = "while(node[i].hasChildNodes()) { node[i].removeChild(node[i].firstChild) }"; 1205 1206 $createVersionNode = "for ( var vers in categories[cat] ) { var opt = document.createElement('option'); opt.appendChild(document.createTextNode(vers)); node[i].appendChild(opt) } "; 1207 $createLanguageNode = "for ( var lang in categories[cat][version] ) { var opt = document.createElement('option'); opt.appendChild(document.createTextNode(categories[cat][version][lang])); node[i].appendChild(opt) } "; 1208 1209 $nodeValues = "var cat = null; var version = null; for( var i=0; i<node.length; i++ ) { if (node[i].name == 'Category') { cat = node[i].value; } if (node[i].name == 'Version') { version = node[i].value; } }"; 1210 $versionNode = "for( var i=0; i<node.length; i++ ) { if (node[i].name != 'Version') { continue; } $removeNodes $createVersionNode break; }"; 1211 $languageNode = "for( var i=0; i<node.length; i++ ) { if (node[i].name != 'Language') { continue; } $removeNodes $createLanguageNode break; }"; 1212 1213 $changeCategory = $JSCategories . " for ( var cat in categories) { if (this.value != cat ) { continue;} $nodes $versionNode" . ( $hasLanguageNode ? "var version = node[i].value; $languageNode " : '' ) . "break; } "; 1214 $changeVersion = $JSCategories . " $nodes $nodeValues $languageNode"; 1215 1216 return array($categories, $changeCategory, $changeVersion); 1217 } 1218 1219 function setUTF8Collation() { 1220 $this->database->databaseConnection->query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'"); 1221 $this->database->databaseConnection->query("SET CHARACTER SET 'utf8'"); 1222 } 1223 1224 /** 1225 * Allow the plugin to prevent DokuWiki creating a second instance of itself 1226 * 1227 * @return bool true if the plugin can not be instantiated more than once 1228 */ 1229 function isSingleton() { 1230 return true; 1231 } 1232 1233 /** 1234 * Pr�fen, ob die aktuelle Version schonmal hinsichtlich der Datenbankanbindung gepr�ft wurde 1235 */ 1236 function currentVersionChecked() { 1237 if ( !file_exists( dirname(__FILE__).'/.translationcheck' ) ) { 1238 return false; 1239 } 1240 1241 $checkDate = implode('', file( dirname(__FILE__).'/.translationcheck' ) ); 1242 $hash = confToHash(dirname(__FILE__).'/info.txt'); 1243 return $hash['date'] == trim($checkDate); 1244 } 1245 1246 /** 1247 * Set the current Version to be checked 1248 */ 1249 function setCurrentVersionChecked() { 1250 1251 $file = dirname(__FILE__).'/.translationcheck'; 1252 $fh = fopen($file, 'w'); 1253 if ( !$fh ) { 1254 msg('Could not write version check file.'); 1255 return false; 1256 } 1257 1258 $hash = confToHash(dirname(__FILE__).'/info.txt'); 1259 fwrite( $fh, $hash['date']); 1260 fclose($fh); 1261 1262 return true; 1263 } 1264} 1265 1266//Setup VIM: ex: et ts=4 enc=utf-8 :