5
* @version $Id: acp_language.php,v 1.59 2007/10/14 15:46:07 acydburn Exp $
6
* @copyright (c) 2005 phpBB Group
7
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
14
if (!defined('IN_PHPBB'))
26
var $language_header = '';
27
var $lang_header = '';
29
var $language_file = '';
30
var $language_directory = '';
32
function main($id, $mode)
34
global $config, $db, $user, $auth, $template, $cache;
35
global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
36
global $safe_mode, $file_uploads;
38
include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
40
$this->default_variables();
42
// Check and set some common vars
44
$action = (isset($_POST['update_details'])) ? 'update_details' : '';
45
$action = (isset($_POST['download_file'])) ? 'download_file' : $action;
46
$action = (isset($_POST['upload_file'])) ? 'upload_file' : $action;
47
$action = (isset($_POST['upload_data'])) ? 'upload_data' : $action;
48
$action = (isset($_POST['submit_file'])) ? 'submit_file' : $action;
49
$action = (isset($_POST['remove_store'])) ? 'details' : $action;
51
$submit = (empty($action) && !isset($_POST['update']) && !isset($_POST['test_connection'])) ? false : true;
52
$action = (empty($action)) ? request_var('action', '') : $action;
54
$form_name = 'acp_lang';
55
add_form_key('acp_lang');
57
$lang_id = request_var('id', 0);
58
if (isset($_POST['missing_file']))
60
$missing_file = request_var('missing_file', array('' => 0));
61
list($_REQUEST['language_file'], ) = array_keys($missing_file);
64
$selected_lang_file = request_var('language_file', '|common.' . $phpEx);
66
list($this->language_directory, $this->language_file) = explode('|', $selected_lang_file);
68
$this->language_directory = basename($this->language_directory);
69
$this->language_file = basename($this->language_file);
71
$user->add_lang('acp/language');
72
$this->tpl_name = 'acp_language';
73
$this->page_title = 'ACP_LANGUAGE_PACKS';
75
if ($submit && $action == 'upload_data' && request_var('test_connection', ''))
77
$test_connection = false;
78
$action = 'upload_file';
79
$method = request_var('method', '');
81
include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
86
$transfer = new ftp(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
90
$transfer = new ftp_fsock(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
94
trigger_error($user->lang['INVALID_UPLOAD_METHOD'], E_USER_ERROR);
98
$test_connection = $transfer->open_session();
99
$transfer->close_session();
106
include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
108
$method = request_var('method', '');
110
if (!class_exists($method))
112
trigger_error('Method does not exist.', E_USER_ERROR);
115
$requested_data = call_user_func(array($method, 'data'));
116
foreach ($requested_data as $data => $default)
118
$template->assign_block_vars('data', array(
120
'NAME' => $user->lang[strtoupper($method . '_' . $data)],
121
'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'],
122
'DEFAULT' => (!empty($_REQUEST[$data])) ? request_var($data, '') : $default
126
$hidden_data = build_hidden_fields(array(
127
'file' => $this->language_file,
128
'dir' => $this->language_directory,
129
'language_file' => $selected_lang_file,
133
$hidden_data .= build_hidden_fields(array('entry' => $_POST['entry']), true, STRIP);
135
$template->assign_vars(array(
138
'U_ACTION' => $this->u_action . "&id=$lang_id&action=upload_data",
139
'U_BACK' => $this->u_action . "&id=$lang_id&action=details&language_file=" . urlencode($selected_lang_file),
140
'HIDDEN' => $hidden_data,
142
'S_CONNECTION_SUCCESS' => (request_var('test_connection', '') && $test_connection === true) ? true : false,
143
'S_CONNECTION_FAILED' => (request_var('test_connection', '') && $test_connection !== true) ? true : false
147
case 'update_details':
149
if (!$submit || !check_form_key($form_name))
151
trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING);
156
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
160
FROM ' . LANG_TABLE . "
161
WHERE lang_id = $lang_id";
162
$result = $db->sql_query($sql);
163
$row = $db->sql_fetchrow($result);
164
$db->sql_freeresult($result);
167
'lang_english_name' => request_var('lang_english_name', $row['lang_english_name']),
168
'lang_local_name' => utf8_normalize_nfc(request_var('lang_local_name', $row['lang_local_name'], true)),
169
'lang_author' => utf8_normalize_nfc(request_var('lang_author', $row['lang_author'], true)),
172
$db->sql_query('UPDATE ' . LANG_TABLE . '
173
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
174
WHERE lang_id = ' . $lang_id);
176
add_log('admin', 'LOG_LANGUAGE_PACK_UPDATED', $sql_ary['lang_english_name']);
178
trigger_error($user->lang['LANGUAGE_DETAILS_UPDATED'] . adm_back_link($this->u_action));
182
case 'download_file':
185
if (!$submit || !check_form_key($form_name))
187
trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING);
190
if (!$lang_id || empty($_POST['entry']))
192
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
195
if ($this->language_directory != 'email' && !is_array($_POST['entry']))
197
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
200
if (!$this->language_file || (!$this->language_directory && !in_array($this->language_file, $this->main_files)))
202
trigger_error($user->lang['NO_FILE_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING);
206
FROM ' . LANG_TABLE . "
207
WHERE lang_id = $lang_id";
208
$result = $db->sql_query($sql);
209
$row = $db->sql_fetchrow($result);
210
$db->sql_freeresult($result);
214
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
217
// Before we attempt to write anything let's check if the admin really chose a correct filename
218
switch ($this->language_directory)
221
// Get email templates
222
$email_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt');
223
$email_files = $email_files['email/'];
225
if (!in_array($this->language_file, $email_files))
227
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
233
$acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx);
234
$acp_files = $acp_files['acp/'];
236
if (!in_array($this->language_file, $acp_files))
238
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
244
$mods_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx);
245
$mods_files = (isset($mods_files['mods/'])) ? $mods_files['mods/'] : array();
247
if (!in_array($this->language_file, $mods_files))
249
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
254
if (!in_array($this->language_file, $this->main_files))
256
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
263
$mkdir_ary = array('language', 'language/' . $row['lang_iso']);
265
if ($this->language_directory)
267
$mkdir_ary[] = 'language/' . $row['lang_iso'] . '/' . $this->language_directory;
270
foreach ($mkdir_ary as $dir)
272
$dir = $phpbb_root_path . 'store/' . $dir;
276
if (!@mkdir($dir, 0777))
278
trigger_error("Could not create directory $dir", E_USER_ERROR);
285
// Get target filename for storage folder
286
$filename = $this->get_filename($row['lang_iso'], $this->language_directory, $this->language_file, true, true);
287
$fp = @fopen($phpbb_root_path . $filename, 'wb');
291
trigger_error(sprintf($user->lang['UNABLE_TO_WRITE_FILE'], $filename) . adm_back_link($this->u_action . '&id=' . $lang_id . '&action=details&language_file=' . urlencode($selected_lang_file)), E_USER_WARNING);
294
if ($this->language_directory == 'email')
297
$entry = $this->prepare_lang_entry($_POST['entry'], false);
302
$name = (($this->language_directory) ? $this->language_directory . '_' : '') . $this->language_file;
303
$header = str_replace(array('{FILENAME}', '{LANG_NAME}', '{CHANGED}', '{AUTHOR}'), array($name, $row['lang_english_name'], date('Y-m-d', time()), $row['lang_author']), $this->language_file_header);
305
if (strpos($this->language_file, 'help_') === 0)
308
$header .= '$help = array(' . "\n";
309
fwrite($fp, $header);
311
foreach ($_POST['entry'] as $key => $value)
313
if (!is_array($value))
318
$entry = "\tarray(\n";
320
foreach ($value as $_key => $_value)
322
$entry .= "\t\t" . (int) $_key . "\t=> '" . $this->prepare_lang_entry($_value) . "',\n";
329
$footer = ");\n\n?>";
330
fwrite($fp, $footer);
335
$header .= $this->lang_header;
336
fwrite($fp, $header);
338
foreach ($_POST['entry'] as $key => $value)
340
$entry = $this->format_lang_array($key, $value);
344
$footer = "));\n\n?>";
345
fwrite($fp, $footer);
351
if ($action == 'download_file')
353
header('Pragma: no-cache');
354
header('Content-Type: application/octetstream; name="' . $this->language_file . '"');
355
header('Content-disposition: attachment; filename=' . $this->language_file);
357
$fp = @fopen($phpbb_root_path . $filename, 'rb');
358
while ($buffer = fread($fp, 1024))
364
add_log('admin', 'LOG_LANGUAGE_FILE_SUBMITTED', $this->language_file);
368
else if ($action == 'upload_data')
370
$sql = 'SELECT lang_iso
371
FROM ' . LANG_TABLE . "
372
WHERE lang_id = $lang_id";
373
$result = $db->sql_query($sql);
374
$row = $db->sql_fetchrow($result);
375
$db->sql_freeresult($result);
377
$file = request_var('file', '');
378
$dir = request_var('dir', '');
380
$selected_lang_file = $dir . '|' . $file;
382
$old_file = '/' . $this->get_filename($row['lang_iso'], $dir, $file, false, true);
383
$lang_path = 'language/' . $row['lang_iso'] . '/' . (($dir) ? $dir . '/' : '');
385
include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
386
$method = request_var('method', '');
388
if ($method != 'ftp' && $method != 'ftp_fsock')
390
trigger_error($user->lang['INVALID_UPLOAD_METHOD'], E_USER_ERROR);
393
$transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
395
if (($result = $transfer->open_session()) !== true)
397
trigger_error($user->lang[$result] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file)), E_USER_WARNING);
400
$transfer->rename($lang_path . $file, $lang_path . $file . '.bak');
401
$result = $transfer->copy_file('store/' . $lang_path . $file, $lang_path . $file);
403
if ($result === false)
405
// If failed, try to rename again and print error out...
406
$transfer->delete_file($lang_path . $file);
407
$transfer->rename($lang_path . $file . '.bak', $lang_path . $file);
409
trigger_error($user->lang['UPLOAD_FAILED'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file)), E_USER_WARNING);
412
$transfer->close_session();
414
// Remove from storage folder
415
if (file_exists($phpbb_root_path . 'store/' . $lang_path . $file))
417
@unlink($phpbb_root_path . 'store/' . $lang_path . $file);
420
add_log('admin', 'LOG_LANGUAGE_FILE_REPLACED', $file);
422
trigger_error($user->lang['UPLOAD_COMPLETED'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file)));
425
add_log('admin', 'LOG_LANGUAGE_FILE_SUBMITTED', $this->language_file);
434
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
437
$this->page_title = 'LANGUAGE_PACK_DETAILS';
440
FROM ' . LANG_TABLE . '
441
WHERE lang_id = ' . $lang_id;
442
$result = $db->sql_query($sql);
443
$lang_entries = $db->sql_fetchrow($result);
444
$db->sql_freeresult($result);
446
$lang_iso = $lang_entries['lang_iso'];
447
$missing_vars = $missing_files = array();
449
// Get email templates
450
$email_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'email', 'txt');
451
$email_files = $email_files['email/'];
454
$acp_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'acp', $phpEx);
455
$acp_files = $acp_files['acp/'];
458
$mods_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'mods', $phpEx);
459
$mods_files = (isset($mods_files['mods/'])) ? $mods_files['mods/'] : array();
461
// Check if our current filename matches the files
462
switch ($this->language_directory)
465
if (!in_array($this->language_file, $email_files))
467
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
472
if (!in_array($this->language_file, $acp_files))
474
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
479
if (!in_array($this->language_file, $mods_files))
481
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
486
if (!in_array($this->language_file, $this->main_files))
488
trigger_error($user->lang['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action . '&action=details&id=' . $lang_id), E_USER_WARNING);
492
if (isset($_POST['remove_store']))
494
$store_filename = $this->get_filename($lang_iso, $this->language_directory, $this->language_file, true, true);
496
if (file_exists($phpbb_root_path . $store_filename))
498
@unlink($phpbb_root_path . $store_filename);
502
include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
504
$methods = transfer::methods();
506
foreach ($methods as $method)
508
$template->assign_block_vars('buttons', array(
513
$template->assign_vars(array(
515
'U_ACTION' => $this->u_action . "&action=details&id=$lang_id",
516
'U_BACK' => $this->u_action,
517
'LANG_LOCAL_NAME' => $lang_entries['lang_local_name'],
518
'LANG_ENGLISH_NAME' => $lang_entries['lang_english_name'],
519
'LANG_ISO' => $lang_entries['lang_iso'],
520
'LANG_AUTHOR' => $lang_entries['lang_author'],
521
'ALLOW_UPLOAD' => sizeof($methods)
525
// If current lang is different from the default lang, then first try to grab missing/additional vars
526
if ($lang_iso != $config['default_lang'])
528
$is_missing_var = false;
530
foreach ($this->main_files as $file)
532
if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file)))
534
$missing_vars[$file] = $this->compare_language_files($config['default_lang'], $lang_iso, '', $file);
536
if (sizeof($missing_vars[$file]))
538
$is_missing_var = true;
543
$missing_files[] = $this->get_filename($lang_iso, '', $file);
547
// Now go through acp/mods directories
548
foreach ($acp_files as $file)
550
if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'acp', $file)))
552
$missing_vars['acp/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'acp', $file);
554
if (sizeof($missing_vars['acp/' . $file]))
556
$is_missing_var = true;
561
$missing_files[] = $this->get_filename($lang_iso, 'acp', $file);
565
if (sizeof($mods_files))
567
foreach ($mods_files as $file)
569
if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'mods', $file)))
571
$missing_vars['mods/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'mods', $file);
573
if (sizeof($missing_vars['mods/' . $file]))
575
$is_missing_var = true;
580
$missing_files[] = $this->get_filename($lang_iso, 'mods', $file);
585
// More missing files... for example email templates?
586
foreach ($email_files as $file)
588
if (!file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'email', $file)))
590
$missing_files[] = $this->get_filename($lang_iso, 'email', $file);
594
if (sizeof($missing_files))
596
$template->assign_vars(array(
597
'S_MISSING_FILES' => true,
598
'L_MISSING_FILES' => sprintf($user->lang['THOSE_MISSING_LANG_FILES'], $lang_entries['lang_local_name']),
599
'MISSING_FILES' => implode('<br />', $missing_files))
605
$template->assign_vars(array(
606
'S_MISSING_VARS' => true,
607
'L_MISSING_VARS_EXPLAIN' => sprintf($user->lang['THOSE_MISSING_LANG_VARIABLES'], $lang_entries['lang_local_name']),
608
'U_MISSING_ACTION' => $this->u_action . "&action=$action&id=$lang_id")
611
foreach ($missing_vars as $file => $vars)
618
$template->assign_block_vars('missing', array(
620
'TPL' => $this->print_language_entries($vars, '', false),
621
'KEY' => (strpos($file, '/') === false) ? '|' . $file : str_replace('/', '|', $file))
627
// Main language files
628
$s_lang_options = '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang['LANGUAGE_FILES'] . '</option>';
629
foreach ($this->main_files as $file)
631
if (strpos($file, 'help_') === 0)
636
$prefix = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true))) ? '* ' : '';
638
$selected = (!$this->language_directory && $this->language_file == $file) ? ' selected="selected"' : '';
639
$s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>';
643
$s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang['HELP_FILES'] . '</option>';
644
foreach ($this->main_files as $file)
646
if (strpos($file, 'help_') !== 0)
651
$prefix = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true))) ? '* ' : '';
653
$selected = (!$this->language_directory && $this->language_file == $file) ? ' selected="selected"' : '';
654
$s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>';
657
// Now every other language directory
658
$check_files = array('email', 'acp', 'mods');
660
foreach ($check_files as $check)
662
if (!sizeof(${$check . '_files'}))
667
$s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang[strtoupper($check) . '_FILES'] . '</option>';
669
foreach (${$check . '_files'} as $file)
671
$prefix = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, $check, $file, true, true))) ? '* ' : '';
673
$selected = ($this->language_directory == $check && $this->language_file == $file) ? ' selected="selected"' : '';
674
$s_lang_options .= '<option value="' . $check . '|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>';
678
// Get Language Entries - if saved within store folder, we take this one (with the option to remove it)
681
$is_email_file = ($this->language_directory == 'email') ? true : false;
682
$is_help_file = (strpos($this->language_file, 'help_') === 0) ? true : false;
684
$file_from_store = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, true, true))) ? true : false;
685
$no_store_filename = $this->get_filename($lang_iso, $this->language_directory, $this->language_file);
687
if (!$file_from_store && !file_exists($phpbb_root_path . $no_store_filename))
689
$print_message = sprintf($user->lang['MISSING_LANGUAGE_FILE'], $no_store_filename);
695
$lang = file_get_contents($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, $file_from_store));
700
include($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory, $this->language_file, $file_from_store));
709
$print_message = (($this->language_directory) ? $this->language_directory . '/' : '') . $this->language_file;
712
// Normal language pack entries
713
$template->assign_vars(array(
714
'U_ENTRY_ACTION' => $this->u_action . "&action=details&id=$lang_id#entries",
715
'S_EMAIL_FILE' => $is_email_file,
716
'S_FROM_STORE' => $file_from_store,
717
'S_LANG_OPTIONS' => $s_lang_options,
718
'PRINT_MESSAGE' => $print_message,
725
$name = (($this->language_directory) ? $this->language_directory . '/' : '') . $this->language_file;
727
if (isset($missing_vars[$name]) && sizeof($missing_vars[$name]))
729
$tpl .= $this->print_language_entries($missing_vars[$name], '* ');
732
$tpl .= $this->print_language_entries($lang);
734
$template->assign_var('TPL', $tpl);
739
$template->assign_vars(array(
754
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
758
FROM ' . LANG_TABLE . '
759
WHERE lang_id = ' . $lang_id;
760
$result = $db->sql_query($sql);
761
$row = $db->sql_fetchrow($result);
762
$db->sql_freeresult($result);
764
if ($row['lang_iso'] == $config['default_lang'])
766
trigger_error($user->lang['NO_REMOVE_DEFAULT_LANG'] . adm_back_link($this->u_action), E_USER_WARNING);
769
$db->sql_query('DELETE FROM ' . LANG_TABLE . ' WHERE lang_id = ' . $lang_id);
771
$sql = 'UPDATE ' . USERS_TABLE . "
772
SET user_lang = '" . $db->sql_escape($config['default_lang']) . "'
773
WHERE user_lang = '" . $db->sql_escape($row['lang_iso']) . "'";
774
$db->sql_query($sql);
776
// We also need to remove the translated entries for custom profile fields - we want clean tables, don't we?
777
$sql = 'DELETE FROM ' . PROFILE_LANG_TABLE . ' WHERE lang_id = ' . $lang_id;
778
$db->sql_query($sql);
780
$sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE . ' WHERE lang_id = ' . $lang_id;
781
$db->sql_query($sql);
783
$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . " WHERE image_lang = '" . $db->sql_escape($row['lang_iso']) . "'";
784
$result = $db->sql_query($sql);
786
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
788
add_log('admin', 'LOG_LANGUAGE_PACK_DELETED', $row['lang_english_name']);
790
trigger_error(sprintf($user->lang['LANGUAGE_PACK_DELETED'], $row['lang_english_name']) . adm_back_link($this->u_action));
794
$lang_iso = request_var('iso', '');
795
$lang_iso = basename($lang_iso);
797
if (!$lang_iso || !file_exists("{$phpbb_root_path}language/$lang_iso/iso.txt"))
799
trigger_error($user->lang['LANGUAGE_PACK_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
802
$file = file("{$phpbb_root_path}language/$lang_iso/iso.txt");
806
'name' => trim(htmlspecialchars($file[0])),
807
'local_name'=> trim(htmlspecialchars($file[1], ENT_COMPAT, 'UTF-8')),
808
'author' => trim(htmlspecialchars($file[2], ENT_COMPAT, 'UTF-8'))
812
$sql = 'SELECT lang_iso
813
FROM ' . LANG_TABLE . "
814
WHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'";
815
$result = $db->sql_query($sql);
816
$row = $db->sql_fetchrow($result);
817
$db->sql_freeresult($result);
821
trigger_error($user->lang['LANGUAGE_PACK_ALREADY_INSTALLED'] . adm_back_link($this->u_action), E_USER_WARNING);
824
if (!$lang_pack['name'] || !$lang_pack['local_name'])
826
trigger_error($user->lang['INVALID_LANGUAGE_PACK'] . adm_back_link($this->u_action), E_USER_WARNING);
831
'lang_iso' => $lang_pack['iso'],
832
'lang_dir' => $lang_pack['iso'],
833
'lang_english_name' => $lang_pack['name'],
834
'lang_local_name' => $lang_pack['local_name'],
835
'lang_author' => $lang_pack['author']
838
$db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
839
$lang_id = $db->sql_nextid();
841
$valid_localized = array(
842
'icon_back_top', 'icon_contact_aim', 'icon_contact_email', 'icon_contact_icq', 'icon_contact_jabber', 'icon_contact_msnm', 'icon_contact_pm', 'icon_contact_yahoo', 'icon_contact_www', 'icon_post_delete', 'icon_post_edit', 'icon_post_info', 'icon_post_quote', 'icon_post_report', 'icon_user_online', 'icon_user_offline', 'icon_user_profile', 'icon_user_search', 'icon_user_warn', 'button_pm_forward', 'button_pm_new', 'button_pm_reply', 'button_topic_locked', 'button_topic_new', 'button_topic_reply',
848
FROM ' . STYLES_IMAGESET_TABLE;
849
$result = $db->sql_query($sql);
850
while ($imageset_row = $db->sql_fetchrow($result))
852
if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['iso']}/imageset.cfg"))
854
$cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['iso']}/imageset.cfg");
855
foreach ($cfg_data_imageset_data as $image_name => $value)
857
if (strpos($value, '*') !== false)
859
if (substr($value, -1, 1) === '*')
861
list($image_filename, $image_height) = explode('*', $value);
866
list($image_filename, $image_height, $image_width) = explode('*', $value);
871
$image_filename = $value;
872
$image_height = $image_width = 0;
875
if (strpos($image_name, 'img_') === 0 && $image_filename)
877
$image_name = substr($image_name, 4);
878
if (in_array($image_name, $valid_localized))
881
'image_name' => (string) $image_name,
882
'image_filename' => (string) $image_filename,
883
'image_height' => (int) $image_height,
884
'image_width' => (int) $image_width,
885
'imageset_id' => (int) $imageset_row['imageset_id'],
886
'image_lang' => (string) $lang_pack['iso'],
893
$db->sql_freeresult($result);
895
if (sizeof($sql_ary))
897
$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
898
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
901
// Now let's copy the default language entries for custom profile fields for this new language - makes admin's life easier.
902
$sql = 'SELECT lang_id
903
FROM ' . LANG_TABLE . "
904
WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
905
$result = $db->sql_query($sql);
906
$default_lang_id = (int) $db->sql_fetchfield('lang_id');
907
$db->sql_freeresult($result);
909
// From the mysql documentation:
910
// Prior to MySQL 4.0.14, the target table of the INSERT statement cannot appear in the FROM clause of the SELECT part of the query. This limitation is lifted in 4.0.14.
911
// Due to this we stay on the safe side if we do the insertion "the manual way"
913
$sql = 'SELECT field_id, lang_name, lang_explain, lang_default_value
914
FROM ' . PROFILE_LANG_TABLE . '
915
WHERE lang_id = ' . $default_lang_id;
916
$result = $db->sql_query($sql);
918
while ($row = $db->sql_fetchrow($result))
920
$row['lang_id'] = $lang_id;
921
$db->sql_query('INSERT INTO ' . PROFILE_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row));
923
$db->sql_freeresult($result);
925
$sql = 'SELECT field_id, option_id, field_type, lang_value
926
FROM ' . PROFILE_FIELDS_LANG_TABLE . '
927
WHERE lang_id = ' . $default_lang_id;
928
$result = $db->sql_query($sql);
930
while ($row = $db->sql_fetchrow($result))
932
$row['lang_id'] = $lang_id;
933
$db->sql_query('INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $row));
935
$db->sql_freeresult($result);
937
add_log('admin', 'LOG_LANGUAGE_PACK_INSTALLED', $lang_pack['name']);
939
trigger_error(sprintf($user->lang['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']) . adm_back_link($this->u_action));
947
trigger_error($user->lang['NO_LANG_ID'] . adm_back_link($this->u_action), E_USER_WARNING);
951
FROM ' . LANG_TABLE . '
952
WHERE lang_id = ' . $lang_id;
953
$result = $db->sql_query($sql);
954
$row = $db->sql_fetchrow($result);
955
$db->sql_freeresult($result);
957
$use_method = request_var('use_method', '');
958
$methods = array('.tar');
960
$available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib');
961
foreach ($available_methods as $type => $module)
963
if (!@extension_loaded($module))
971
// Let the user decide in which format he wants to have the pack
974
$this->page_title = 'SELECT_DOWNLOAD_FORMAT';
977
foreach ($methods as $method)
979
$radio_buttons .= '<label><input type="radio"' . ((!$radio_buttons) ? ' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . '</label>';
982
$template->assign_vars(array(
983
'S_SELECT_METHOD' => true,
984
'U_BACK' => $this->u_action,
985
'U_ACTION' => $this->u_action . "&action=$action&id=$lang_id",
986
'RADIO_BUTTONS' => $radio_buttons)
992
if (!in_array($use_method, $methods))
994
$use_method = '.tar';
997
include_once($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
999
if ($use_method == '.zip')
1001
$compress = new compress_zip('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method);
1005
$compress = new compress_tar('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method, $use_method);
1008
// Get email templates
1009
$email_templates = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt');
1010
$email_templates = $email_templates['email/'];
1013
$acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx);
1014
$acp_files = $acp_files['acp/'];
1017
$mod_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx);
1018
$mod_files = (isset($mod_files['mods/'])) ? $mod_files['mods/'] : array();
1021
$this->add_to_archive($compress, $this->main_files, $row['lang_iso']);
1023
// Add search files if they exist...
1024
if (file_exists($phpbb_root_path . 'language/' . $row['lang_iso'] . '/search_ignore_words.' . $phpEx))
1026
$this->add_to_archive($compress, array("search_ignore_words.$phpEx"), $row['lang_iso']);
1029
if (file_exists($phpbb_root_path . 'language/' . $row['lang_iso'] . '/search_synonyms.' . $phpEx))
1031
$this->add_to_archive($compress, array("search_synonyms.$phpEx"), $row['lang_iso']);
1034
// Write files in folders
1035
$this->add_to_archive($compress, $email_templates, $row['lang_iso'], 'email');
1036
$this->add_to_archive($compress, $acp_files, $row['lang_iso'], 'acp');
1037
$this->add_to_archive($compress, $mod_files, $row['lang_iso'], 'mods');
1040
$iso_src = htmlspecialchars_decode($row['lang_english_name']) . "\n";
1041
$iso_src .= htmlspecialchars_decode($row['lang_local_name']) . "\n";
1042
$iso_src .= htmlspecialchars_decode($row['lang_author']);
1043
$compress->add_data($iso_src, 'language/' . $row['lang_iso'] . '/iso.txt');
1046
$compress->add_data('', 'language/' . $row['lang_iso'] . '/index.html');
1047
$compress->add_data('', 'language/' . $row['lang_iso'] . '/email/index.html');
1048
$compress->add_data('', 'language/' . $row['lang_iso'] . '/acp/index.html');
1050
if (sizeof($mod_files))
1052
$compress->add_data('', 'language/' . $row['lang_iso'] . '/mods/index.html');
1057
$compress->download('lang_' . $row['lang_iso']);
1058
@unlink($phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method);
1065
$sql = 'SELECT user_lang, COUNT(user_lang) AS lang_count
1066
FROM ' . USERS_TABLE . '
1067
GROUP BY user_lang';
1068
$result = $db->sql_query($sql);
1070
$lang_count = array();
1071
while ($row = $db->sql_fetchrow($result))
1073
$lang_count[$row['user_lang']] = $row['lang_count'];
1075
$db->sql_freeresult($result);
1078
FROM ' . LANG_TABLE . '
1079
ORDER BY lang_english_name';
1080
$result = $db->sql_query($sql);
1082
$installed = array();
1084
while ($row = $db->sql_fetchrow($result))
1086
$installed[] = $row['lang_iso'];
1087
$tagstyle = ($row['lang_iso'] == $config['default_lang']) ? '*' : '';
1089
$template->assign_block_vars('lang', array(
1090
'U_DETAILS' => $this->u_action . "&action=details&id={$row['lang_id']}",
1091
'U_DOWNLOAD' => $this->u_action . "&action=download&id={$row['lang_id']}",
1092
'U_DELETE' => $this->u_action . "&action=delete&id={$row['lang_id']}",
1094
'ENGLISH_NAME' => $row['lang_english_name'],
1096
'LOCAL_NAME' => $row['lang_local_name'],
1097
'ISO' => $row['lang_iso'],
1098
'USED_BY' => (isset($lang_count[$row['lang_iso']])) ? $lang_count[$row['lang_iso']] : 0,
1101
$db->sql_freeresult($result);
1103
$new_ary = $iso = array();
1104
$dp = @opendir("{$phpbb_root_path}language");
1108
while (($file = readdir($dp)) !== false)
1110
if ($file[0] != '.' && file_exists("{$phpbb_root_path}language/$file/iso.txt"))
1112
if (!in_array($file, $installed))
1114
if ($iso = file("{$phpbb_root_path}language/$file/iso.txt"))
1116
if (sizeof($iso) == 3)
1118
$new_ary[$file] = array(
1120
'name' => trim($iso[0]),
1121
'local_name'=> trim($iso[1]),
1122
'author' => trim($iso[2])
1134
if (sizeof($new_ary))
1136
foreach ($new_ary as $iso => $lang_ary)
1138
$template->assign_block_vars('notinst', array(
1139
'ISO' => htmlspecialchars($lang_ary['iso']),
1140
'LOCAL_NAME' => htmlspecialchars($lang_ary['local_name'], ENT_COMPAT, 'UTF-8'),
1141
'NAME' => htmlspecialchars($lang_ary['name'], ENT_COMPAT, 'UTF-8'),
1142
'U_INSTALL' => $this->u_action . '&action=install&iso=' . urlencode($lang_ary['iso']))
1152
* Set default language variables/header
1154
function default_variables()
1158
$this->language_file_header = '<?php
1161
* {FILENAME} [{LANG_NAME}]
1164
* @version $' . 'Id: ' . '$
1165
* @copyright (c) ' . date('Y') . ' phpBB Group
1166
* @author {CHANGED} - {AUTHOR}
1167
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
1174
if (!defined(\'IN_PHPBB\'))
1179
if (empty($lang) || !is_array($lang))
1184
// DEVELOPERS PLEASE NOTE
1186
// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
1188
// Placeholders can now contain order information, e.g. instead of
1189
// \'Page %s of %s\' you can (and should) write \'Page %1$s of %2$s\', this allows
1190
// translators to re-order the output of data while ensuring it remains correct
1192
// You do not need this where single placeholders are used, e.g. \'Message %d\' is fine
1193
// equally where a string contains only two placeholders which are used to wrap text
1194
// in a url you again do not need to specify an order e.g., \'Click %sHERE%s\' is fine
1197
$this->lang_header = '
1198
$lang = array_merge($lang, array(
1201
// Language files in language root directory
1202
$this->main_files = array("common.$phpEx", "groups.$phpEx", "install.$phpEx", "mcp.$phpEx", "memberlist.$phpEx", "posting.$phpEx", "search.$phpEx", "ucp.$phpEx", "viewforum.$phpEx", "viewtopic.$phpEx", "help_bbcode.$phpEx", "help_faq.$phpEx");
1206
* Get filename/location of language file
1208
function get_filename($lang_iso, $directory, $filename, $check_store = false, $only_return_filename = false)
1210
global $phpbb_root_path, $safe_mode;
1212
$check_filename = "language/$lang_iso/" . (($directory) ? $directory . '/' : '') . $filename;
1216
$check_store_filename = ($safe_mode) ? "store/langfile_{$lang_iso}" . (($directory) ? '_' . $directory : '') . "_{$filename}" : "store/language/$lang_iso/" . (($directory) ? $directory . '/' : '') . $filename;
1218
if (!$only_return_filename && file_exists($phpbb_root_path . $check_store_filename))
1220
return $check_store_filename;
1222
else if ($only_return_filename)
1224
return $check_store_filename;
1228
return $check_filename;
1232
* Add files to archive
1234
function add_to_archive(&$compress, $filelist, $lang_iso, $directory = '')
1236
global $phpbb_root_path;
1238
foreach ($filelist as $file)
1240
// Get source filename
1241
$source = $this->get_filename($lang_iso, $directory, $file, true);
1242
$destination = 'language/' . $lang_iso . '/' . (($directory) ? $directory . '/' : '') . $file;
1244
// Add file to archive
1245
$compress->add_custom_file($phpbb_root_path . $source, $destination);
1250
* Little helper to add some hardcoded template bits
1252
function add_input_field()
1254
$keys = func_get_args();
1256
$non_static = array_shift($keys);
1257
$value = array_shift($keys);
1261
return '<strong>' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '</strong>';
1264
// If more then 270 characters, then we present a textarea, else an input field
1265
$textarea = (utf8_strlen($value) > 270) ? true : false;
1268
$tpl .= ($textarea) ? '<textarea name="' : '<input type="text" name="';
1269
$tpl .= 'entry[' . implode('][', array_map('utf8_htmlspecialchars', $keys)) . ']"';
1271
$tpl .= ($textarea) ? ' cols="80" rows="5" class="langvalue">' : ' class="langvalue" value="';
1272
$tpl .= htmlspecialchars($value, ENT_COMPAT, 'UTF-8');
1273
$tpl .= ($textarea) ? '</textarea>' : '" />';
1279
* Print language entries
1281
function print_language_entries(&$lang_ary, $key_prefix = '', $input_field = true)
1285
foreach ($lang_ary as $key => $value)
1287
if (is_array($value))
1292
<td class="row3" colspan="2">' . htmlspecialchars($key_prefix, ENT_COMPAT, 'UTF-8') . '<strong>' . htmlspecialchars($key, ENT_COMPAT, 'UTF-8') . '</strong></td>
1295
foreach ($value as $_key => $_value)
1297
if (is_array($_value))
1302
<td class="row3" colspan="2">' . htmlspecialchars($key_prefix, ENT_COMPAT, 'UTF-8') . ' <strong>' . htmlspecialchars($_key, ENT_COMPAT, 'UTF-8') . '</strong></td>
1305
foreach ($_value as $__key => $__value)
1310
<td class="row1" style="white-space: nowrap;">' . htmlspecialchars($key_prefix, ENT_COMPAT, 'UTF-8') . '<strong>' . htmlspecialchars($__key, ENT_COMPAT, 'UTF-8') . '</strong></td>
1313
$tpl .= $this->add_input_field($input_field, $__value, $key, $_key, $__key);
1324
<td class="row1" style="white-space: nowrap;">' . htmlspecialchars($key_prefix, ENT_COMPAT, 'UTF-8') . '<strong>' . htmlspecialchars($_key, ENT_COMPAT, 'UTF-8') . '</strong></td>
1327
$tpl .= $this->add_input_field($input_field, $_value, $key, $_key);
1336
<td class="spacer" colspan="2"> </td>
1344
<td class="row1" style="white-space: nowrap;">' . htmlspecialchars($key_prefix, ENT_COMPAT, 'UTF-8') . '<strong>' . htmlspecialchars($key, ENT_COMPAT, 'UTF-8') . '</strong></td>
1347
$tpl .= $this->add_input_field($input_field, $value, $key);
1358
* Compare two language files
1360
function compare_language_files($source_lang, $dest_lang, $directory, $file)
1362
global $phpbb_root_path, $phpEx;
1364
$return_ary = array();
1367
include("{$phpbb_root_path}language/{$source_lang}/" . (($directory) ? $directory . '/' : '') . $file);
1368
$lang_entry_src = $lang;
1372
if (!file_exists($phpbb_root_path . $this->get_filename($dest_lang, $directory, $file, true)))
1377
include($phpbb_root_path . $this->get_filename($dest_lang, $directory, $file, true));
1379
$lang_entry_dst = $lang;
1383
$diff_array_keys = array_diff(array_keys($lang_entry_src), array_keys($lang_entry_dst));
1384
unset($lang_entry_dst);
1386
foreach ($diff_array_keys as $key)
1388
$return_ary[$key] = $lang_entry_src[$key];
1391
unset($lang_entry_src);
1397
* Return language string value for storage
1399
function prepare_lang_entry($text, $store = true)
1401
$text = (STRIP) ? stripslashes($text) : $text;
1403
// Adjust for storage...
1406
$text = str_replace("'", "\\'", str_replace('\\', '\\\\', $text));
1413
* Format language array for storage
1415
function format_lang_array($key, $value, $tabs = "\t")
1419
if (!is_array($value))
1421
$entry .= "{$tabs}'" . $this->prepare_lang_entry($key) . "'\t=> '" . $this->prepare_lang_entry($value) . "',\n";
1425
$_tabs = $tabs . "\t";
1426
$entry .= "\n{$tabs}'" . $this->prepare_lang_entry($key) . "'\t=> array(\n";
1428
foreach ($value as $_key => $_value)
1430
$entry .= $this->format_lang_array($_key, $_value, $_tabs);
1433
$entry .= "{$tabs}),\n\n";
b'\\ No newline at end of file'