1<?php
2/**
3 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
4 * @author     i-net software <tools@inetsoftware.de>
5 * @author  Gerry Weissbach <gweissbach@inetsoftware.de>
6 */
7
8// must be run within Dokuwiki
9if(!defined('DOKU_INC')) die();
10
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
12require_once(DOKU_PLUGIN.'syntax.php');
13
14/**
15 * All DokuWiki plugins to extend the parser/rendering mechanism
16 * need to inherit from this class
17 */
18class syntax_plugin_translator_translator extends DokuWiki_Syntax_Plugin {
19
20	var $functions = null;
21	var $category = null;
22	var $languages = null;
23	var $currentLanguage = null;
24	var $currentVersion = null;
25	var $additionalLanguage = null;
26	var $version = null;
27
28	/**
29	 * return some info
30	 */
31	function getInfo(){
32		return array_merge(confToHash(dirname(__FILE__).'/../info.txt'), array(
33				'name' => 'Translator (Syntax Component)',
34		));
35	}
36
37	function getType(){ return 'substition'; }
38	function getPType(){ return 'block'; }
39	function getSort(){ return 110; }
40
41
42
43	/**
44	 * Connect pattern to lexer
45	 */
46	function connectTo($mode){
47		$this->Lexer->addSpecialPattern('~~TRANSLATOR~~',$mode,'plugin_translator_translator');
48	}
49	/**
50	 * Handle the match
51	 */
52	function handle($match, $state, $pos, &$handler){
53
54		return array('translator');
55	}
56
57	/**
58	 *  Render output
59	 */
60	function render($mode, &$renderer, $data) {
61		global $ID;
62
63		if ($mode == 'xhtml') {
64
65			$renderer->nocache();
66
67			// Instantiate the helper
68			if ( !$this->functions =& plugin_load('helper', 'translator') ) {
69				print $this->lang['helpermissing'];
70				return false;
71			}
72
73			// Connect to the Database and load Languages
74			$this->functions->init_database();
75
76			// Setup the Variables
77			$this->category = $_REQUEST['Category'];
78			$this->languages = $this->functions->_getLanguages();
79			$this->version = $_REQUEST['Version'];
80			$this->currentLanguage = $_REQUEST['Language'];
81			$this->currentVersion = $_REQUEST['Version'];
82			$this->additionalLanguage = $_REQUEST['AdditionalLanguage'];
83
84			// check Database
85			$renderer->doc .= '<div id="translator">';
86
87			if ( count($this->functions->revertableUpload) > 0 ) {
88				$renderer->doc .= $this->functions->_revertManager($this, $this->functions->revertableUpload);
89			}
90
91			// test this is the setup page
92			if ( empty($this->category) || empty($this->currentLanguage) ) {
93				$this->_setupTranslator($renderer);
94				$this->_printStatistics($renderer);
95			} else {
96
97				if ( $this->languages === false ) {
98					$renderer->doc .= $this->locale_xhtml('noauth');
99					return false;
100				}
101
102				// Print the Translator
103				$this->_printTranslator($renderer, intval($_REQUEST['start']), intval($_REQUEST['amount']), $_REQUEST['Display'], $_REQUEST['Filter']);
104			}
105
106			$renderer->doc .= '</div>';
107
108			return true;
109		}
110
111		return true;
112	}
113
114	/*
115	 * Create a Setup Fieldset with Category and Language
116	 */
117	function _setupTranslator(&$renderer) {
118		global $INFO;
119
120		$renderer->doc .= $this->locale_xhtml('setup');
121
122		$form = $this->_startFieldSet($this->getLang('SelectCategory'), 'translator_setup');
123
124		list($categories, $changeCategory, $changeVersion) = $this->functions->_getChangerJS(false);
125
126		$form->addElement(form_makeListboxField('Category', array_keys($categories), $_REQUEST['Category'], $this->getLang('Category') . ':', null, null, array('onchange' => $changeCategory)));
127		$form->addElement(form_makeTag('br'));
128
129		$form->addElement(form_makeListboxField('Version', (empty($categories[$_REQUEST['Category']]['Versions']) ? array('none given') : array_keys($categories[$_REQUEST['Category']]['Versions'])), $_REQUEST['Version'], $this->getLang('Version') . ':', null, null, array('onchange' => $changeVersion)));
130		$form->addElement(form_makeTag('br'));
131
132		$form->addElement(form_makeField('submit', 'fn[setup]', $this->getLang('Show'), ''));
133
134		$renderer->doc .= $this->_finishFieldset($form);
135		return true;
136	}
137
138	/*
139	 * Find all Categories and create a form field out of them
140	 */
141	function _categorySelection(&$form, $currentCategory) {
142		$this->functions->database->prepare("SELECT CategoryID, Name, FileName FROM tblCategory;");
143		$this->functions->database->execute();
144
145		if ( $this->functions->database->num_rows() == 0 ) {
146			$form;
147			return false;
148		}
149
150		$categories = array(); $data = array(); $this->functions->database->bind_assoc($data);
151		while ( $this->functions->database->fetch() ) {
152			$categories[] = $data['Name'];
153		}
154
155		$form->addElement(form_makeListboxField('Category', $categories, $currentCategory, $this->getLang('Category') . ':', null, null, array('onchange' => 'var node = this.parentNode.parentNode.getElementsByTagName(\'select\'); for( var i=0; i<node.length; i++ ) { if (node[i].name != \'Version\') { continue; } node[i].parentNode.parentNode.removeChild(node[i].parentNode); break; }')));
156		$form->addElement(form_makeTag('br'));
157
158		return true;
159	}
160
161	/*
162	 * Print the Translators main View
163	 */
164	function _printTranslator(&$renderer, $start=null, $amount=null, $display=null, $filter=null) {
165
166		if ( empty($display) ) {
167			$display = $this->getLang('notTranslated');
168		}
169
170		// Translatation Matrix
171		list($matrix, $max) = $this->functions->_getTranslationMatrix($this->category, $this->version, $this->currentLanguage, $this->additionalLanguage, $start, $amount, $display, $filter);
172		list($categoryID) = $this->functions->_getCategoryFromName($this->category);
173
174		//print_r($matrix); exit;
175
176
177		if ( $matrix === false || count($matrix) == 0 ) {
178			$renderer->doc .= $this->locale_xhtml('nothingtodo');
179			$renderer->doc .= $this->_setPages($start, $amount, $max, $display, true);
180			return false;
181		}
182
183		$masterLanguage = empty($this->additionalLanguage) ?  $this->getConf('default_language') : $this->additionalLanguage;
184
185		// Print Table Headers
186		$form = $this->_startFieldSet($this->getLang('Translator'), "translator_do");
187
188		$form->addElement(form_makeOpenTag("table", array('class' => 'translation_table')));
189
190		$form->addElement(form_makeOpenTag("colgroup"));
191		$form->addElement(form_makeOpenTag("col", array('width' => 2)));
192		$form->addElement(form_makeOpenTag("col", array('width' => 4)));
193		$form->addElement(form_makeOpenTag("col", array('width' => 4)));
194		$form->addElement(form_makeOpenTag("col", array('width' => 1)));
195		$form->addElement(form_makeCloseTag("colgroup"));
196
197
198		$form->addElement(form_makeOpenTag("tr"));
199
200		$form->addElement(form_makeOpenTag("th"));
201		$form->addElement($this->getLang('RessourceKeyName'));
202		$form->addElement(form_makeCloseTag("th"));
203
204		$form->addElement(form_makeOpenTag("th"));
205		$form->addElement($this->getLang('MasterValue') . " ($masterLanguage)");
206		$form->addElement(form_makeCloseTag("th"));
207
208		$form->addElement(form_makeOpenTag("th", array('class' => 'translation_editor')));
209		$form->addElement($this->getLang('TranslationValue') . " ({$this->currentLanguage})");
210		$form->addElement(form_makeCloseTag("th"));
211
212		$form->addElement(form_makeCloseTag("tr"));
213
214		$rowHighlight = true;
215		$onclick = array(	'class' => 'row_' . intval($rowHighlight),
216																'onclick' => 'var elem=getElementsByClass("edit", this, "textarea");
217																				elem[0].focus(); elem[0].select();',
218		);
219
220
221		// Print the Matrix in a table
222		foreach ( $matrix as $line ) {
223
224			//print $line['ResourceKey'] . "<br>\n";
225
226			$masterValue = !empty($line['AdditionalValue']) ? $line['AdditionalValue'] : $line['MasterValue'];
227			$form->addElement(form_makeOpenTag("tr"));
228
229			$form->addElement(form_makeOpenTag("td", array_merge(array('class' => 'resourceKey', 'title' => hsc(stripslashes($line['ResourceKey'])) ), $onclick)));
230			$form->addElement(stripslashes(utf8_decode($line['ResourceKey'])));
231			$form->addElement(form_makeCloseTag("td"));
232
233			$form->addElement(form_makeOpenTag("td", $onclick));
234
235			$textAreaWidth = 70;
236			$form->addElement(form_makeOpenTag("textarea",	array(	'rows' => (ceil(strlen($masterValue) / $textAreaWidth)),
237																	'class' => 'edit',
238																	'style' => 'width: 95%;',
239																	'readonly' => 'readonly')
240			));
241			$form->addElement(hsc(stripslashes($masterValue)));
242			$form->addElement(form_makeCloseTag("textarea"));
243			$form->addElement(form_makeCloseTag("td"));
244
245			$form->addElement(form_makeOpenTag("td", array('class' => 'translation_editor')));
246
247			$form->addElement(form_makeOpenTag("textarea",	array(	'rows' => (ceil(strlen($masterValue) / $textAreaWidth)),
248																	'style' => 'width: 95%;',
249																	'class' => 'edit',
250																	'name' => "translation[{$line['KeyID']}]",
251																	'id' => "translation_{$line['KeyID']}",)
252			));
253			$form->addElement(stripslashes($line['TranslationValue']));
254			$form->addElement(form_makeCloseTag("textarea"));
255			if ( auth_ismanager() && !empty($line['TranslationValue']) ) $form->addElement("(" . tpl_link(wl($ID, array('do' => 'admin', 'page' => 'translator', 'manageUser' => $line['User'] ), true), $line['User'], null, true) . ")");
256			$form->addElement(form_makeCloseTag("td"));
257			$form->addElement(form_makeOpenTag("td"));
258			$form->addElement(form_makeOpenTag("button", array('onclick' => "translator.run('{$this->currentLanguage}', 'translation_{$line['KeyID']}', '{$line['KeyID']}', '{$categoryID}'); return false;")));
259			$form->addElement('google');
260			$form->addElement(form_makeCloseTag("button"));
261			$form->addElement(form_makeCloseTag("td"));
262
263			$form->addElement(form_makeCloseTag("tr"));
264
265			$rowHighlight = !$rowHighlight;
266		}
267
268		$form->addElement(form_makeCloseTag("table"));
269
270
271		$form->addElement(form_makeField('submit', 'fn[setup]', $this->getLang('Cancel'), ''));
272		$form->addElement(form_makeField('submit', 'fn[translate]', $this->getLang('Submit'), ''));
273
274		$renderer->doc .= $this->_setPages($start, $amount, $max, $display);
275		$renderer->doc .= $this->_finishFieldset($form);
276		$renderer->doc .= $this->_setPages($start, $amount, $max, $display);
277
278		return true;
279	}
280
281	/*
282	 * Display Header and Footer to chane the current selection or page
283	 */
284	function _setPages($start, $amount, $max, $display, $printGoBack=false) {
285		global $ID;
286
287		if ( empty($amount)  || $amount == 0 ) $amount = 25;
288		list($categoryID) = $this->functions->_getCategoryFromName($this->category);
289		$onChangeEvent = 'document.getElementById(\'fn[setpage][' . $start . ']ID\').click();';
290
291		$form = $this->_startFieldSet($this->getLang('selectedOptions'));
292		$form->addElement("<div class='language' style='width:150px;'>{$this->getLang('Category')}:</div><div style='width:200px;float:right'>$this->category</div>");
293		$form->addElement(form_makeTag('br'));
294		$form->addElement("<div class='language' style='width:150px;'>{$this->getLang('Version')}:</div><div style='width:200px;float:right'>$this->version</div");
295		$form->addElement(form_makeTag('br'));
296		$form->addElement("<div class='language' style='width:150px;'>{$this->getLang('Permalink')}:</div><div style='width:200px;float:right'>" . tpl_link(wl($ID, array('Category' => $this->category, 'Version' => $this->version, 'Language' => $this->currentLanguage, 'AdditionalLanguage' => $this->additionalLanguage, 'start' => $start, 'amount' => $amount, 'Display' => $display), true), $this->getLang('RightClickNCopy'), null, true) . "</div>");
297		$form->addElement(form_makeTag('br'));
298
299		$form->addElement(form_makeListboxField('newAdditionalLanguage', $this->functions->_getAvailableLanguages($categoryID), $_REQUEST['AdditionalLanguage'], $this->getLang('DisplayReferenceLanguage') . ':', null, null, array('onchange' => $onChangeEvent)));
300		$form->addElement(form_makeTag('br'));
301		$form->addElement(form_makeListboxField('newAmount', array('25', '50', '100', '200'), $amount, $this->getLang('DisplayAmount') . ':', null, null, array('onchange' => $onChangeEvent)));
302		$form->addElement(form_makeTag('br'));
303		$form->addElement(form_makeTextField('Filter', $_REQUEST['Filter'], 'Filter' . ':', '', 'short'));
304		$form->addElement(form_makeTag('br'));
305		$form->addElement(form_makeField('submit', 'fn[setpage][0]', 'submit', '', 'fn[setpage][0]ID', 'setpage right'));
306		$form->addElement(form_makeTag('br'));
307
308		$countOfPages = ceil($max / $amount);
309		for( $i=1; $i <= $countOfPages; $i++ ) {
310			$currentPage = floor($start/$amount) == $i-1 ? ' current' : '';
311			$form->addElement(form_makeField('submit', 'fn[setpage][' . ($i-1)*$amount . ']', $i, '', 'fn[setpage][' . ($i-1)*$amount . ']ID', 'setpage' . $currentPage));
312		}
313
314		if ( $printGoBack ) {
315			$form->addElement(form_makeTag('br'));
316			$form->addElement(form_makeField('submit', 'fn[setup]', $this->getLang('backToFirstPage'), ''));
317		}
318
319		return $this->_finishFieldset($form);
320	}
321
322	/*
323	 * Print the Main Selector with Statsitics for selected Categroy
324	 */
325	function _printStatistics($renderer) {
326		global $INFO;
327
328		// If no categroy selected return
329		if ( empty ( $this->category ) || empty ( $this->currentVersion ) ) {
330			return false;
331		}
332
333		list($cagtegoryID, $filename) = $this->functions->_getCategoryFromName($this->category);
334		$masterValues = $this->functions->_getAmountOfMasterValues($cagtegoryID, $this->currentVersion);
335		if ( empty($masterValues) || $masterValues == 0 ) {
336			return;
337		}
338
339		$renderer->doc .= $this->locale_xhtml('statistics');
340
341		// Start building Form for each version
342		$form = $this->_startFieldSet( $this->category . ' ' . $this->getLang('Version') . ' ' . $this->currentVersion );
343		$languages = $this->functions->_getAvailableLanguages($cagtegoryID, $this->currentVersion);
344
345		// Hidden global Information
346		$form->addHidden('Version', $this->currentVersion);
347		$form->addHidden('Category', $this->category);
348
349		$form->addElement(form_makeOpenTag('p'));
350		$form->addElement($this->getLang('AmountOfMasterValues') . ': ' . $masterValues);
351		$form->addElement(form_makeCloseTag('p'));
352
353		// merge Languages from user and available languages from database
354		$languages = array_unique(array_merge($languages, explode('|', $this->languages)));
355		sort($languages);
356
357		foreach( $languages as $language ) {
358			if ( $language == $this->getConf('default_language') ) continue;
359			if ( empty( $language ) ) continue;
360
361			$currentAmount = $this->functions->_getAmountOfLanguageValues($cagtegoryID, $this->currentVersion, $language);
362
363			// Output informative block
364			$form->addElement(form_makeOpenTag('div', array('class' => 'language') ));
365			$form->addElement($this->functions->_downloadLink($this->category, $this->currentVersion, $language, '[' . $language . ']', true));
366			$form->addElement(form_makeCloseTag('div'));
367
368			$form->addElement(form_makeOpenTag('div', array('class' => 'language') ));
369			$form->addElement($this->functions->_downloadLink($this->category, $this->currentVersion, $language, '[unicoded]'));
370			$form->addElement(form_makeCloseTag('div'));
371
372			$form->addElement(form_makeOpenTag('div', array('class' => 'percent')));
373			$form->addElement(sprintf("%.1f%%", $currentAmount / $masterValues * 100 ));
374			$form->addElement(form_makeCloseTag('div'));
375
376			// If user has rights to use language, display buttons
377			if ( in_array($language, explode('|', $this->languages)) ) {
378				$form->addElement(form_makeField('submit', 'fn[setup][' . $language . '][' . $this->getLang('all') . ']', $this->getLang('all'), $this->getLang('Translate') . ':') );
379				if ( $currentAmount > 0 ) $form->addElement(form_makeField('submit', 'fn[setup][' . $language . '][' . $this->getLang('translated') . ']', $this->getLang('translated'), '') );
380				if ( $currentAmount < $masterValues ) $form->addElement(form_makeField('submit', 'fn[setup][' . $language . '][' . $this->getLang('notTranslated') . ']', $this->getLang('notTranslated'), '') );
381			}
382			$form->addElement(form_makeTag('br'));
383		}
384
385		$renderer->doc .= $this->_finishFieldset($form);
386	}
387
388	/*
389	 * Fieldsets for the syntax page
390	 */
391	function _startFieldSet($name, $hid='translator', $formType=null) {
392		global $ID;
393
394		$form = new Doku_Form($hid, wl($ID), 'post', $formType);
395		$form->startFieldset( $name );
396		$form->addHidden('Category', $_REQUEST['Category']);
397		$form->addHidden('Version', $_REQUEST['Version']);
398		$form->addHidden('Display', $_REQUEST['Display']);
399		$form->addHidden('Language', $_REQUEST['Language']);
400		$form->addHidden('AdditionalLanguage', $_REQUEST['AdditionalLanguage']);
401		$form->addHidden('start', $_REQUEST['start']);
402		$form->addHidden('amount', $_REQUEST['amount']);
403		return $form;
404	}
405
406	/*
407	 * Finish a fieldset and capture the output to put it into the renderer document
408	 */
409	function _finishFieldset($form=null) {
410		if ( empty($form) ) return;
411
412		$form->endFieldset();
413		return $this->functions->capture_form_output($form);
414	}
415
416	/**
417	 * Allow the plugin to prevent DokuWiki creating a second instance of itself
418	 *
419	 * @return bool   true if the plugin can not be instantiated more than once
420	 */
421	function isSingleton() {
422		return true;
423	}
424}
425