6 * @copyright (c) 2005 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
18 var $language_header = '';
19 var $lang_header = '';
21 var $language_file = '';
22 var $language_directory = '';
24 function main($id, $mode)
26 global $config, $db, $user, $auth, $template, $cache;
27 global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
28 global $safe_mode, $file_uploads;
30 include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx);
32 $this->default_variables();
34 // Check and set some common vars
35 $action = request_var('action', '');
37 $action = (isset($_POST['update_details'])) ?
'update_details' : $action;
38 $action = (isset($_POST['download_file'])) ?
'download_file' : $action;
39 $action = (isset($_POST['upload_file'])) ?
'upload_file' : $action;
40 $action = (isset($_POST['upload_data'])) ?
'upload_data' : $action;
41 $action = (isset($_POST['submit_file'])) ?
'submit_file' : $action;
42 $action = (isset($_POST['remove_store'])) ?
'details' : $action;
44 $lang_id = request_var('id', 0);
45 if (isset($_POST['missing_file']))
47 $missing_file = request_var('missing_file', array('' => 0));
48 list($_REQUEST['language_file'], ) = array_keys($missing_file);
51 $selected_lang_file = request_var('language_file', '|common.' . $phpEx);
53 list($this->language_directory
, $this->language_file
) = explode('|', $selected_lang_file);
55 $this->language_directory
= basename($this->language_directory
);
56 $this->language_file
= basename($this->language_file
);
58 $user->add_lang('acp/language');
59 $this->tpl_name
= 'acp_language';
60 $this->page_title
= 'ACP_LANGUAGE_PACKS';
62 if ($action == 'upload_data' && request_var('test_connection', ''))
64 $test_connection = false;
65 $action = 'upload_file';
66 $method = request_var('method', '');
68 include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
73 $transfer = new ftp(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
77 $transfer = new ftp_fsock(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
81 trigger_error($user->lang
['INVALID_UPLOAD_METHOD'], E_USER_ERROR
);
85 $test_connection = $transfer->open_session();
86 $transfer->close_session();
92 include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
94 $method = request_var('method', '');
96 $requested_data = call_user_func(array($method, 'data'));
97 foreach ($requested_data as $data => $default)
99 $template->assign_block_vars('data', array(
101 'NAME' => $user->lang
[strtoupper($method . '_' . $data)],
102 'EXPLAIN' => $user->lang
[strtoupper($method . '_' . $data) . '_EXPLAIN'],
103 'DEFAULT' => (!empty($_REQUEST[$data])) ?
request_var($data, '') : $default
107 $hidden_data = build_hidden_fields(array(
108 'file' => $this->language_file
,
109 'dir' => $this->language_directory
,
110 'language_file' => $selected_lang_file,
114 $hidden_data .= build_hidden_fields(array('entry' => $_POST['entry']), true, STRIP
);
116 $template->assign_vars(array(
119 'U_ACTION' => $this->u_action
. "&id=$lang_id&action=upload_data",
120 'U_BACK' => $this->u_action
. "&id=$lang_id&action=details&language_file=" . urlencode($selected_lang_file),
121 'HIDDEN' => $hidden_data,
123 'S_CONNECTION_SUCCESS' => (request_var('test_connection', '') && $test_connection === true) ?
true : false,
124 'S_CONNECTION_FAILED' => (request_var('test_connection', '') && $test_connection !== true) ?
true : false
128 case 'update_details':
132 trigger_error($user->lang
['NO_LANG_ID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
136 FROM ' . LANG_TABLE
. "
137 WHERE lang_id = $lang_id";
138 $result = $db->sql_query($sql);
139 $row = $db->sql_fetchrow($result);
140 $db->sql_freeresult($result);
143 'lang_english_name' => request_var('lang_english_name', $row['lang_english_name']),
144 'lang_local_name' => request_var('lang_local_name', $row['lang_local_name'], true),
145 'lang_author' => request_var('lang_author', $row['lang_author'], true),
148 $db->sql_query('UPDATE ' . LANG_TABLE
. '
149 SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
150 WHERE lang_id = ' . $lang_id);
152 add_log('admin', 'LOG_LANGUAGE_PACK_UPDATED', $sql_ary['lang_english_name']);
154 trigger_error($user->lang
['LANGUAGE_DETAILS_UPDATED'] . adm_back_link($this->u_action
));
158 case 'download_file':
161 if (!$lang_id ||
empty($_POST['entry']))
163 trigger_error($user->lang
['NO_LANG_ID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
166 if (!$this->language_file ||
(!$this->language_directory
&& !in_array($this->language_file
, $this->main_files
)))
168 trigger_error($user->lang
['NO_FILE_SELECTED'] . adm_back_link($this->u_action
), E_USER_WARNING
);
172 FROM ' . LANG_TABLE
. "
173 WHERE lang_id = $lang_id";
174 $result = $db->sql_query($sql);
175 $row = $db->sql_fetchrow($result);
176 $db->sql_freeresult($result);
180 $mkdir_ary = array('language', 'language/' . $row['lang_iso']);
182 if ($this->language_directory
)
184 $mkdir_ary[] = 'language/' . $row['lang_iso'] . '/' . $this->language_directory
;
187 foreach ($mkdir_ary as $dir)
189 $dir = $phpbb_root_path . 'store/' . $dir;
193 if (!@mkdir
($dir, 0777))
195 trigger_error("Could not create directory $dir", E_USER_ERROR
);
202 // Get target filename for storage folder
203 $filename = $this->get_filename($row['lang_iso'], $this->language_directory
, $this->language_file
, true, true);
204 $fp = fopen($phpbb_root_path . $filename, 'wb');
208 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
);
211 if ($this->language_directory
== 'email')
214 $entry = $this->prepare_lang_entry($_POST['entry'], false);
219 $name = (($this->language_directory
) ?
$this->language_directory
. '_' : '') . $this->language_file
;
220 $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
);
222 if (strpos($this->language_file
, 'help_') === 0)
225 $header .= '$help = array(' . "\n";
226 fwrite($fp, $header);
228 foreach ($_POST['entry'] as $key => $value)
230 if (!is_array($value))
235 $entry = "\tarray(\n";
237 foreach ($value as $_key => $_value)
239 $entry .= "\t\t" . (int) $_key . "\t=> '" . $this->prepare_lang_entry($_value) . "',\n";
246 $footer = ");\n\n?>";
247 fwrite($fp, $footer);
252 $header .= $this->lang_header
;
253 fwrite($fp, $header);
255 foreach ($_POST['entry'] as $key => $value)
257 $entry = $this->format_lang_array($key, $value);
261 $footer = "));\n\n?>";
262 fwrite($fp, $footer);
268 if ($action == 'download_file')
270 header('Pragma: no-cache');
271 header('Content-Type: application/octetstream; name="' . $this->language_file
. '"');
272 header('Content-disposition: attachment; filename=' . $this->language_file
);
274 $fp = fopen($phpbb_root_path . $filename, 'rb');
275 while ($buffer = fread($fp, 1024))
281 add_log('admin', 'LOG_LANGUAGE_FILE_SUBMITTED', $this->language_file
);
285 else if ($action == 'upload_data')
287 $sql = 'SELECT lang_iso
288 FROM ' . LANG_TABLE
. "
289 WHERE lang_id = $lang_id";
290 $result = $db->sql_query($sql);
291 $row = $db->sql_fetchrow($result);
292 $db->sql_freeresult($result);
294 $file = request_var('file', '');
295 $dir = request_var('dir', '');
297 $selected_lang_file = $dir . '|' . $file;
299 $old_file = '/' . $this->get_filename($row['lang_iso'], $dir, $file, false, true);
300 $lang_path = 'language/' . $row['lang_iso'] . '/' . (($dir) ?
$dir . '/' : '');
302 include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
303 $method = request_var('method', '');
305 if ($method != 'ftp' && $method != 'ftp_fsock')
307 trigger_error($user->lang
['INVALID_UPLOAD_METHOD'], E_USER_ERROR
);
310 $transfer = new $method(request_var('host', ''), request_var('username', ''), request_var('password', ''), request_var('root_path', ''), request_var('port', ''), request_var('timeout', ''));
312 if (($result = $transfer->open_session()) !== true)
314 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
);
317 $transfer->rename($lang_path . $file, $lang_path . $file . '.bak');
318 $result = $transfer->copy_file('store/' . $lang_path . $file, $lang_path . $file);
320 if ($result === false)
322 // If failed, try to rename again and print error out...
323 $transfer->delete_file($lang_path . $file);
324 $transfer->rename($lang_path . $file . '.bak', $lang_path . $file);
326 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
);
329 $transfer->close_session();
331 // Remove from storage folder
332 @unlink
($phpbb_root_path . 'store/' . $lang_path . $file);
334 add_log('admin', 'LOG_LANGUAGE_FILE_REPLACED', $file);
336 trigger_error($user->lang
['UPLOAD_COMPLETED'] . adm_back_link($this->u_action
. '&action=details&id=' . $lang_id . '&language_file=' . urlencode($selected_lang_file)));
339 add_log('admin', 'LOG_LANGUAGE_FILE_SUBMITTED', $this->language_file
);
348 trigger_error($user->lang
['NO_LANG_ID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
351 $this->page_title
= 'LANGUAGE_PACK_DETAILS';
354 FROM ' . LANG_TABLE
. '
355 WHERE lang_id = ' . $lang_id;
356 $result = $db->sql_query($sql);
357 $lang_entries = $db->sql_fetchrow($result);
358 $db->sql_freeresult($result);
360 $lang_iso = $lang_entries['lang_iso'];
361 $missing_vars = $missing_files = array();
363 // Get email templates
364 $email_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'email', 'txt');
365 $email_files = $email_files['email/'];
368 $acp_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'acp', $phpEx);
369 $acp_files = $acp_files['acp/'];
372 $mods_files = filelist($phpbb_root_path . 'language/' . $config['default_lang'], 'mods', $phpEx);
373 $mods_files = (isset($mods_files['mods/'])) ?
$mods_files['mods/'] : array();
375 // Check if our current filename matches the files
376 switch ($this->language_directory
)
379 if (!in_array($this->language_file
, $email_files))
381 trigger_error($user->lang
['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action
. '&action=details&id=' . $lang_id), E_USER_WARNING
);
386 if (!in_array($this->language_file
, $acp_files))
388 trigger_error($user->lang
['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action
. '&action=details&id=' . $lang_id), E_USER_WARNING
);
393 if (!in_array($this->language_file
, $mods_files))
395 trigger_error($user->lang
['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action
. '&action=details&id=' . $lang_id), E_USER_WARNING
);
400 if (!in_array($this->language_file
, $this->main_files
))
402 trigger_error($user->lang
['WRONG_LANGUAGE_FILE'] . adm_back_link($this->u_action
. '&action=details&id=' . $lang_id), E_USER_WARNING
);
406 if (isset($_POST['remove_store']))
408 $store_filename = $this->get_filename($lang_iso, $this->language_directory
, $this->language_file
, true, true);
409 @unlink
($phpbb_root_path . $store_filename);
412 include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx);
414 $methods = transfer
::methods();
416 foreach ($methods as $method)
418 $template->assign_block_vars('buttons', array(
423 $template->assign_vars(array(
425 'U_ACTION' => $this->u_action
. "&action=details&id=$lang_id",
426 'U_BACK' => $this->u_action
,
427 'LANG_LOCAL_NAME' => $lang_entries['lang_local_name'],
428 'LANG_ENGLISH_NAME' => $lang_entries['lang_english_name'],
429 'LANG_ISO' => $lang_entries['lang_iso'],
430 'LANG_AUTHOR' => $lang_entries['lang_author'],
431 'ALLOW_UPLOAD' => sizeof($methods)
435 // If current lang is different from the default lang, then first try to grab missing/additional vars
436 if ($lang_iso != $config['default_lang'])
438 $is_missing_var = false;
440 foreach ($this->main_files
as $file)
442 if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file)))
444 $missing_vars[$file] = $this->compare_language_files($config['default_lang'], $lang_iso, '', $file);
446 if (sizeof($missing_vars[$file]))
448 $is_missing_var = true;
453 $missing_files[] = $this->get_filename($lang_iso, '', $file);
457 // Now go through acp/mods directories
458 foreach ($acp_files as $file)
460 if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'acp', $file)))
462 $missing_vars['acp/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'acp', $file);
464 if (sizeof($missing_vars['acp/' . $file]))
466 $is_missing_var = true;
471 $missing_files[] = $this->get_filename($lang_iso, 'acp', $file);
475 if (sizeof($mods_files))
477 foreach ($mods_files as $file)
479 if (file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'mods', $file)))
481 $missing_vars['mods/' . $file] = $this->compare_language_files($config['default_lang'], $lang_iso, 'mods', $file);
483 if (sizeof($missing_vars['mods/' . $file]))
485 $is_missing_var = true;
490 $missing_files[] = $this->get_filename($lang_iso, 'mods', $file);
495 // More missing files... for example email templates?
496 foreach ($email_files as $file)
498 if (!file_exists($phpbb_root_path . $this->get_filename($lang_iso, 'email', $file)))
500 $missing_files[] = $this->get_filename($lang_iso, 'email', $file);
504 if (sizeof($missing_files))
506 $template->assign_vars(array(
507 'S_MISSING_FILES' => true,
508 'L_MISSING_FILES' => sprintf($user->lang
['THOSE_MISSING_LANG_FILES'], $lang_entries['lang_local_name']),
509 'MISSING_FILES' => implode('<br />', $missing_files))
515 $template->assign_vars(array(
516 'S_MISSING_VARS' => true,
517 'L_MISSING_VARS_EXPLAIN' => sprintf($user->lang
['THOSE_MISSING_LANG_VARIABLES'], $lang_entries['lang_local_name']),
518 'U_MISSING_ACTION' => $this->u_action
. "&action=$action&id=$lang_id")
521 foreach ($missing_vars as $file => $vars)
528 $template->assign_block_vars('missing', array(
530 'TPL' => $this->print_language_entries($vars, '', false),
531 'KEY' => (strpos($file, '/') === false) ?
'|' . $file : str_replace('/', '|', $file))
537 // Main language files
538 $s_lang_options = '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang
['LANGUAGE_FILES'] . '</option>';
539 foreach ($this->main_files
as $file)
541 if (strpos($file, 'help_') === 0)
546 $prefix = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true))) ?
'* ' : '';
548 $selected = (!$this->language_directory
&& $this->language_file
== $file) ?
' selected="selected"' : '';
549 $s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>';
553 $s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang
['HELP_FILES'] . '</option>';
554 foreach ($this->main_files
as $file)
556 if (strpos($file, 'help_') !== 0)
561 $prefix = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, '', $file, true, true))) ?
'* ' : '';
563 $selected = (!$this->language_directory
&& $this->language_file
== $file) ?
' selected="selected"' : '';
564 $s_lang_options .= '<option value="|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>';
567 // Now every other language directory
568 $check_files = array('email', 'acp', 'mods');
570 foreach ($check_files as $check)
572 if (!sizeof($
{$check . '_files'}))
577 $s_lang_options .= '<option value="|common.' . $phpEx . '" class="sep">' . $user->lang
[strtoupper($check) . '_FILES'] . '</option>';
579 foreach ($
{$check . '_files'} as $file)
581 $prefix = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, $check, $file, true, true))) ?
'* ' : '';
583 $selected = ($this->language_directory
== $check && $this->language_file
== $file) ?
' selected="selected"' : '';
584 $s_lang_options .= '<option value="' . $check . '|' . $file . '"' . $selected . '>' . $prefix . $file . '</option>';
588 // Get Language Entries - if saved within store folder, we take this one (with the option to remove it)
591 $is_email_file = ($this->language_directory
== 'email') ?
true : false;
592 $is_help_file = (strpos($this->language_file
, 'help_') === 0) ?
true : false;
594 $file_from_store = (file_exists($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory
, $this->language_file
, true, true))) ?
true : false;
595 $no_store_filename = $this->get_filename($lang_iso, $this->language_directory
, $this->language_file
);
597 if (!$file_from_store && !file_exists($phpbb_root_path . $no_store_filename))
599 $print_message = sprintf($user->lang
['MISSING_LANGUAGE_FILE'], $no_store_filename);
605 $lang = file_get_contents($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory
, $this->language_file
, $file_from_store));
610 include($phpbb_root_path . $this->get_filename($lang_iso, $this->language_directory
, $this->language_file
, $file_from_store));
619 $print_message = (($this->language_directory
) ?
$this->language_directory
. '/' : '') . $this->language_file
;
622 // Normal language pack entries
623 $template->assign_vars(array(
624 'U_ENTRY_ACTION' => $this->u_action
. "&action=details&id=$lang_id#entries",
625 'S_EMAIL_FILE' => $is_email_file,
626 'S_FROM_STORE' => $file_from_store,
627 'S_LANG_OPTIONS' => $s_lang_options,
628 'PRINT_MESSAGE' => $print_message,
635 $name = (($this->language_directory
) ?
$this->language_directory
. '/' : '') . $this->language_file
;
637 if (isset($missing_vars[$name]) && sizeof($missing_vars[$name]))
639 $tpl .= $this->print_language_entries($missing_vars[$name], '* ');
642 $tpl .= $this->print_language_entries($lang);
644 $template->assign_var('TPL', $tpl);
649 $template->assign_vars(array(
664 trigger_error($user->lang
['NO_LANG_ID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
668 FROM ' . LANG_TABLE
. '
669 WHERE lang_id = ' . $lang_id;
670 $result = $db->sql_query($sql);
671 $row = $db->sql_fetchrow($result);
672 $db->sql_freeresult($result);
674 if ($row['lang_iso'] == $config['default_lang'])
676 trigger_error($user->lang
['NO_REMOVE_DEFAULT_LANG'] . adm_back_link($this->u_action
), E_USER_WARNING
);
679 $db->sql_query('DELETE FROM ' . LANG_TABLE
. ' WHERE lang_id = ' . $lang_id);
681 $sql = 'UPDATE ' . USERS_TABLE
. "
682 SET user_lang = '" . $db->sql_escape($config['default_lang']) . "'
683 WHERE user_lang = '" . $db->sql_escape($row['lang_iso']) . "'";
684 $db->sql_query($sql);
686 // We also need to remove the translated entries for custom profile fields - we want clean tables, don't we?
687 $sql = 'DELETE FROM ' . PROFILE_LANG_TABLE
. ' WHERE lang_id = ' . $lang_id;
688 $db->sql_query($sql);
690 $sql = 'DELETE FROM ' . PROFILE_FIELDS_LANG_TABLE
. ' WHERE lang_id = ' . $lang_id;
691 $db->sql_query($sql);
693 add_log('admin', 'LOG_LANGUAGE_PACK_DELETED', $row['lang_english_name']);
695 trigger_error(sprintf($user->lang
['LANGUAGE_PACK_DELETED'], $row['lang_english_name']) . adm_back_link($this->u_action
));
699 $lang_iso = request_var('iso', '');
700 $lang_iso = basename($lang_iso);
702 if (!$lang_iso ||
!file_exists("{$phpbb_root_path}language/$lang_iso/iso.txt"))
704 trigger_error($user->lang
['LANGUAGE_PACK_NOT_EXIST'] . adm_back_link($this->u_action
), E_USER_WARNING
);
707 $file = file("{$phpbb_root_path}language/$lang_iso/iso.txt");
711 'name' => trim(htmlspecialchars($file[0])),
712 'local_name'=> trim(htmlspecialchars($file[1], ENT_COMPAT
, 'UTF-8')),
713 'author' => trim(htmlspecialchars($file[2], ENT_COMPAT
, 'UTF-8'))
717 $sql = 'SELECT lang_iso
718 FROM ' . LANG_TABLE
. "
719 WHERE lang_iso = '" . $db->sql_escape($lang_iso) . "'";
720 $result = $db->sql_query($sql);
721 $row = $db->sql_fetchrow($result);
722 $db->sql_freeresult($result);
726 trigger_error($user->lang
['LANGUAGE_PACK_ALREADY_INSTALLED'] . adm_back_link($this->u_action
), E_USER_WARNING
);
729 if (!$lang_pack['name'] ||
!$lang_pack['local_name'])
731 trigger_error($user->lang
['INVALID_LANGUAGE_PACK'] . adm_back_link($this->u_action
), E_USER_WARNING
);
736 'lang_iso' => $lang_pack['iso'],
737 'lang_dir' => $lang_pack['iso'],
738 'lang_english_name' => $lang_pack['name'],
739 'lang_local_name' => $lang_pack['local_name'],
740 'lang_author' => $lang_pack['author']
743 $db->sql_query('INSERT INTO ' . LANG_TABLE
. ' ' . $db->sql_build_array('INSERT', $sql_ary));
744 $lang_id = $db->sql_nextid();
746 // Now let's copy the default language entries for custom profile fields for this new language - makes admin's life easier.
747 $sql = 'SELECT lang_id
748 FROM ' . LANG_TABLE
. "
749 WHERE lang_iso = '" . $db->sql_escape($config['default_lang']) . "'";
750 $result = $db->sql_query($sql);
751 $default_lang_id = (int) $db->sql_fetchfield('lang_id');
752 $db->sql_freeresult($result);
754 // From the mysql documentation:
755 // 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.
756 // Due to this we stay on the safe side if we do the insertion "the manual way"
758 $sql = 'SELECT field_id, lang_name, lang_explain, lang_default_value
759 FROM ' . PROFILE_LANG_TABLE
. '
760 WHERE lang_id = ' . $default_lang_id;
761 $result = $db->sql_query($sql);
763 while ($row = $db->sql_fetchrow($result))
765 $row['lang_id'] = $lang_id;
766 $db->sql_query('INSERT INTO ' . PROFILE_LANG_TABLE
. ' ' . $db->sql_build_array('INSERT', $row));
768 $db->sql_freeresult($result);
770 $sql = 'SELECT field_id, option_id, field_type, lang_value
771 FROM ' . PROFILE_FIELDS_LANG_TABLE
. '
772 WHERE lang_id = ' . $default_lang_id;
773 $result = $db->sql_query($sql);
775 while ($row = $db->sql_fetchrow($result))
777 $row['lang_id'] = $lang_id;
778 $db->sql_query('INSERT INTO ' . PROFILE_FIELDS_LANG_TABLE
. ' ' . $db->sql_build_array('INSERT', $row));
780 $db->sql_freeresult($result);
782 add_log('admin', 'LOG_LANGUAGE_PACK_INSTALLED', $lang_pack['name']);
784 trigger_error(sprintf($user->lang
['LANGUAGE_PACK_INSTALLED'], $lang_pack['name']) . adm_back_link($this->u_action
));
792 trigger_error($user->lang
['NO_LANG_ID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
796 FROM ' . LANG_TABLE
. '
797 WHERE lang_id = ' . $lang_id;
798 $result = $db->sql_query($sql);
799 $row = $db->sql_fetchrow($result);
800 $db->sql_freeresult($result);
802 $use_method = request_var('use_method', '');
803 $methods = array('.tar');
805 $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib');
806 foreach ($available_methods as $type => $module)
808 if (!@extension_loaded
($module))
816 // Let the user decide in which format he wants to have the pack
819 $this->page_title
= 'SELECT_DOWNLOAD_FORMAT';
822 foreach ($methods as $method)
824 $radio_buttons .= '<input type="radio"' . ((!$radio_buttons) ?
' id="use_method"' : '') . ' class="radio" value="' . $method . '" name="use_method" /> ' . $method . ' ';
827 $template->assign_vars(array(
828 'S_SELECT_METHOD' => true,
829 'U_BACK' => $this->u_action
,
830 'U_ACTION' => $this->u_action
. "&action=$action&id=$lang_id",
831 'RADIO_BUTTONS' => $radio_buttons)
837 if (!in_array($use_method, $methods))
839 $use_method = '.tar';
842 include_once($phpbb_root_path . 'includes/functions_compress.' . $phpEx);
844 if ($use_method == '.zip')
846 $compress = new compress_zip('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method);
850 $compress = new compress_tar('w', $phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method, $use_method);
853 // Get email templates
854 $email_templates = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'email', 'txt');
855 $email_templates = $email_templates['email/'];
858 $acp_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'acp', $phpEx);
859 $acp_files = $acp_files['acp/'];
862 $mod_files = filelist($phpbb_root_path . 'language/' . $row['lang_iso'], 'mods', $phpEx);
863 $mod_files = (isset($mod_files['mods/'])) ?
$mod_files['mods/'] : array();
866 $this->add_to_archive($compress, $this->main_files
, $row['lang_iso']);
868 // Add search files if they exist...
869 if (file_exists($phpbb_root_path . 'language/' . $row['lang_iso'] . '/search_ignore_words.' . $phpEx))
871 $this->add_to_archive($compress, array("search_ignore_words.$phpEx"), $row['lang_iso']);
874 if (file_exists($phpbb_root_path . 'language/' . $row['lang_iso'] . '/search_synonyms.' . $phpEx))
876 $this->add_to_archive($compress, array("search_synonyms.$phpEx"), $row['lang_iso']);
879 // Write files in folders
880 $this->add_to_archive($compress, $email_templates, $row['lang_iso'], 'email');
881 $this->add_to_archive($compress, $acp_files, $row['lang_iso'], 'acp');
882 $this->add_to_archive($compress, $mod_files, $row['lang_iso'], 'mods');
885 $iso_src = htmlspecialchars_decode($row['lang_english_name']) . "\n";
886 $iso_src .= htmlspecialchars_decode($row['lang_local_name']) . "\n";
887 $iso_src .= htmlspecialchars_decode($row['lang_author']);
888 $compress->add_data($iso_src, 'language/' . $row['lang_iso'] . '/iso.txt');
891 $compress->add_data('', 'language/' . $row['lang_iso'] . '/index.html');
892 $compress->add_data('', 'language/' . $row['lang_iso'] . '/email/index.html');
893 $compress->add_data('', 'language/' . $row['lang_iso'] . '/acp/index.html');
895 if (sizeof($mod_files))
897 $compress->add_data('', 'language/' . $row['lang_iso'] . '/mods/index.html');
902 $compress->download('lang_' . $row['lang_iso']);
903 @unlink
($phpbb_root_path . 'store/lang_' . $row['lang_iso'] . $use_method);
910 $sql = 'SELECT user_lang, COUNT(user_lang) AS lang_count
911 FROM ' . USERS_TABLE
. '
913 $result = $db->sql_query($sql);
915 $lang_count = array();
916 while ($row = $db->sql_fetchrow($result))
918 $lang_count[$row['user_lang']] = $row['lang_count'];
920 $db->sql_freeresult($result);
923 FROM ' . LANG_TABLE
. '
924 ORDER BY lang_english_name';
925 $result = $db->sql_query($sql);
927 $installed = array();
929 while ($row = $db->sql_fetchrow($result))
931 $installed[] = $row['lang_iso'];
932 $tagstyle = ($row['lang_iso'] == $config['default_lang']) ?
'*' : '';
934 $template->assign_block_vars('lang', array(
935 'U_DETAILS' => $this->u_action
. "&action=details&id={$row['lang_id']}",
936 'U_DOWNLOAD' => $this->u_action
. "&action=download&id={$row['lang_id']}",
937 'U_DELETE' => $this->u_action
. "&action=delete&id={$row['lang_id']}",
939 'ENGLISH_NAME' => $row['lang_english_name'],
941 'LOCAL_NAME' => $row['lang_local_name'],
942 'ISO' => $row['lang_iso'],
943 'USED_BY' => (isset($lang_count[$row['lang_iso']])) ?
$lang_count[$row['lang_iso']] : 0,
946 $db->sql_freeresult($result);
948 $new_ary = $iso = array();
949 $dp = @opendir
("{$phpbb_root_path}language");
953 while (($file = readdir($dp)) !== false)
955 if ($file[0] != '.' && file_exists("{$phpbb_root_path}language/$file/iso.txt"))
957 if (!in_array($file, $installed))
959 if ($iso = file("{$phpbb_root_path}language/$file/iso.txt"))
961 if (sizeof($iso) == 3)
963 $new_ary[$file] = array(
965 'name' => trim($iso[0]),
966 'local_name'=> trim($iso[1]),
967 'author' => trim($iso[2])
979 if (sizeof($new_ary))
981 foreach ($new_ary as $iso => $lang_ary)
983 $template->assign_block_vars('notinst', array(
984 'ISO' => htmlspecialchars($lang_ary['iso']),
985 'LOCAL_NAME' => htmlspecialchars($lang_ary['local_name'], ENT_COMPAT
, 'UTF-8'),
986 'NAME' => htmlspecialchars($lang_ary['name'], ENT_COMPAT
, 'UTF-8'),
987 'U_INSTALL' => $this->u_action
. '&action=install&iso=' . urlencode($lang_ary['iso']))
997 * Set default language variables/header
999 function default_variables()
1003 $this->language_file_header
= '<?php
1006 * {FILENAME} [{LANG_NAME}]
1009 * @version $' . 'Id: ' . '$
1010 * @copyright (c) ' . date('Y') . ' phpBB Group
1011 * @author {CHANGED} - {AUTHOR}
1012 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
1019 if (empty($lang) || !is_array($lang))
1024 // DEVELOPERS PLEASE NOTE
1026 // All language files should use UTF-8 as their encoding and the files must not contain a BOM.
1028 // Placeholders can now contain order information, e.g. instead of
1029 // \'Page %s of %s\' you can (and should) write \'Page %1$s of %2$s\', this allows
1030 // translators to re-order the output of data while ensuring it remains correct
1032 // You do not need this where single placeholders are used, e.g. \'Message %d\' is fine
1033 // equally where a string contains only two placeholders which are used to wrap text
1034 // in a url you again do not need to specify an order e.g., \'Click %sHERE%s\' is fine
1037 $this->lang_header
= '
1038 $lang = array_merge($lang, array(
1041 // Language files in language root directory
1042 $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");
1046 * Get filename/location of language file
1048 function get_filename($lang_iso, $directory, $filename, $check_store = false, $only_return_filename = false)
1050 global $phpbb_root_path, $safe_mode;
1052 $check_filename = "language/$lang_iso/" . (($directory) ?
$directory . '/' : '') . $filename;
1056 $check_store_filename = ($safe_mode) ?
"store/langfile_{$lang_iso}" . (($directory) ?
'_' . $directory : '') . "_{$filename}" : "store/language/$lang_iso/" . (($directory) ?
$directory . '/' : '') . $filename;
1058 if (!$only_return_filename && file_exists($phpbb_root_path . $check_store_filename))
1060 return $check_store_filename;
1062 else if ($only_return_filename)
1064 return $check_store_filename;
1068 return $check_filename;
1072 * Add files to archive
1074 function add_to_archive(&$compress, $filelist, $lang_iso, $directory = '')
1076 global $phpbb_root_path;
1078 foreach ($filelist as $file)
1080 // Get source filename
1081 $source = $this->get_filename($lang_iso, $directory, $file, true);
1082 $destination = 'language/' . $lang_iso . '/' . (($directory) ?
$directory . '/' : '') . $file;
1084 // Add file to archive
1085 $compress->add_custom_file($phpbb_root_path . $source, $destination);
1090 * Little helper to add some hardcoded template bits
1092 function add_input_field()
1094 $keys = func_get_args();
1096 $non_static = array_shift($keys);
1097 $value = array_shift($keys);
1101 return '<strong>' . htmlspecialchars($value, ENT_COMPAT
, 'UTF-8') . '</strong>';
1104 // If more then 270 characters, then we present a textarea, else an input field
1105 $textarea = (utf8_strlen($value) > 270) ?
true : false;
1108 $tpl .= ($textarea) ?
'<textarea name="' : '<input type="text" name="';
1109 $tpl .= 'entry[' . implode('][', array_map('utf8_htmlspecialchars', $keys)) . ']"';
1111 $tpl .= ($textarea) ?
' cols="80" rows="5" class="langvalue">' : ' class="langvalue" value="';
1112 $tpl .= htmlspecialchars($value, ENT_COMPAT
, 'UTF-8');
1113 $tpl .= ($textarea) ?
'</textarea>' : '" />';
1119 * Print language entries
1121 function print_language_entries(&$lang_ary, $key_prefix = '', $input_field = true)
1125 foreach ($lang_ary as $key => $value)
1127 if (is_array($value))
1132 <td class="row3" colspan="2">' . htmlspecialchars($key_prefix, ENT_COMPAT
, 'UTF-8') . '<strong>' . htmlspecialchars($key, ENT_COMPAT
, 'UTF-8') . '</strong></td>
1135 foreach ($value as $_key => $_value)
1137 if (is_array($_value))
1142 <td class="row3" colspan="2">' . htmlspecialchars($key_prefix, ENT_COMPAT
, 'UTF-8') . ' <strong>' . htmlspecialchars($_key, ENT_COMPAT
, 'UTF-8') . '</strong></td>
1145 foreach ($_value as $__key => $__value)
1150 <td class="row1" style="white-space: nowrap;">' . htmlspecialchars($key_prefix, ENT_COMPAT
, 'UTF-8') . '<strong>' . htmlspecialchars($__key, ENT_COMPAT
, 'UTF-8') . '</strong></td>
1153 $tpl .= $this->add_input_field($input_field, $__value, $key, $_key, $__key);
1164 <td class="row1" style="white-space: nowrap;">' . htmlspecialchars($key_prefix, ENT_COMPAT
, 'UTF-8') . '<strong>' . htmlspecialchars($_key, ENT_COMPAT
, 'UTF-8') . '</strong></td>
1167 $tpl .= $this->add_input_field($input_field, $_value, $key, $_key);
1176 <td class="spacer" colspan="2"> </td>
1184 <td class="row1" style="white-space: nowrap;">' . htmlspecialchars($key_prefix, ENT_COMPAT
, 'UTF-8') . '<strong>' . htmlspecialchars($key, ENT_COMPAT
, 'UTF-8') . '</strong></td>
1187 $tpl .= $this->add_input_field($input_field, $value, $key);
1198 * Compare two language files
1200 function compare_language_files($source_lang, $dest_lang, $directory, $file)
1202 global $phpbb_root_path, $phpEx;
1204 $return_ary = array();
1207 include("{$phpbb_root_path}language/{$source_lang}/" . (($directory) ?
$directory . '/' : '') . $file);
1208 $lang_entry_src = $lang;
1212 if (!file_exists($phpbb_root_path . $this->get_filename($dest_lang, $directory, $file, true)))
1217 include($phpbb_root_path . $this->get_filename($dest_lang, $directory, $file, true));
1219 $lang_entry_dst = $lang;
1223 $diff_array_keys = array_diff(array_keys($lang_entry_src), array_keys($lang_entry_dst));
1224 unset($lang_entry_dst);
1226 foreach ($diff_array_keys as $key)
1228 $return_ary[$key] = $lang_entry_src[$key];
1231 unset($lang_entry_src);
1237 * Return language string value for storage
1239 function prepare_lang_entry($text, $store = true)
1241 $text = (STRIP
) ?
stripslashes($text) : $text;
1243 // Adjust for storage...
1246 $text = str_replace("'", "\\'", str_replace('\\', '\\\\', $text));
1253 * Format language array for storage
1255 function format_lang_array($key, $value, $tabs = "\t")
1259 if (!is_array($value))
1261 $entry .= "{$tabs}'{$key}'\t=> '" . $this->prepare_lang_entry($value) . "',\n";
1265 $_tabs = $tabs . "\t";
1266 $entry .= "\n{$tabs}'{$key}'\t=> array(\n";
1268 foreach ($value as $_key => $_value)
1270 $entry .= $this->format_lang_array($_key, $_value, $_tabs);
1273 $entry .= "{$tabs}),\n\n";