author | Dan |
Tue, 30 Mar 2010 11:37:00 -0400 | |
changeset 1231 | 4797a4a88533 |
parent 1227 | bdac73ed481e |
child 1377 | fa2b0825bbc5 |
permissions | -rw-r--r-- |
<?php /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between * Copyright (C) 2006-2009 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. */ function page_Admin_LangManager() { global $db, $session, $paths, $template, $plugins; // Common objects global $lang; global $cache; if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) { $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>'; echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>'; return; } if ( isset($_POST['action']) ) { $action =& $_POST['action']; // Parse parameters if ( strpos($action, ';') ) { // Parameter section $parms = substr($action, strpos($action, ';') + 1); // Action name section $action = substr($action, 0, strpos($action, ';')); // Match all parameters preg_match_all('/([a-z0-9_]+)=(.+?)(;|$)/', $parms, $matches); $parms = array(); // For each full parameter, assign $parms an associative value foreach ( $matches[0] as $i => $_ ) { $parm = $matches[2][$i]; // Is this parameter in the form of an integer? // (designed to ease validation later) if ( ctype_digit($parm) ) // Yes, run intval(), this enabling is_int()-ish checks $parm = intval($parm); $parms[$matches[1][$i]] = $parm; } } switch ( $action ) { case 'install_language': if ( defined('ENANO_DEMO_MODE') ) { echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; break; } $lang_list = list_available_languages(); // Verify that we have this language's metadata if ( isset($lang_list[@$parms['iso639']]) ) { // From here it's all downhill :-) $lang_code =& $parms['iso639']; $lang_data =& $lang_list[$lang_code]; $result = install_language($lang_code, $lang_data['name_eng'], $lang_data['name']); if ( $result ) { // Language installed. Import the language files. $lang_local = new Language($lang_code); if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) { $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); } else { foreach ( array('core', 'admin', 'tools', 'user') as $file ) { $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); } } unset($lang_local); echo '<div class="info-box">' . $lang->get('acplm_msg_lang_install_success', array('lang_name' => htmlspecialchars($lang_data['name_eng']))) . '</div>'; } } break; case 'modify_language': $lang_id =& $parms['lang_id']; if ( !is_int($lang_id) ) { echo 'Hacking attempt'; break; } if ( isset($parms['finish']) && !empty($_POST['lang_name_native']) && !empty($_POST['lang_name_english']) && !defined('ENANO_DEMO_MODE') ) { // We just did validation above, it's safe to save. $name_native = $db->escape($_POST['lang_name_native']); $name_english = $db->escape($_POST['lang_name_english']); $q = $db->sql_query('UPDATE ' . table_prefix . "language SET lang_name_native = '$name_native', lang_name_default = '$name_english' WHERE lang_id = $lang_id;"); if ( !$q ) $db->_die(); echo '<div class="info-box">' . $lang->get('acplm_msg_basic_save_success') . '</div>'; } else if ( isset($parms['finish']) && defined('ENANO_DEMO_MODE') ) { echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; } // Select language data $q = $db->sql_query('SELECT lang_name_native, lang_name_default, lang_code FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); if ( !$q ) $db->_die(); list($name_native, $name_english, $lang_code) = $db->fetchrow_num(); // Output properties table echo '<h3>' . $lang->get('acplm_heading_modify') . '</h3>'; acp_start_form(); ?> <div class="tblholder"> <table border="0" cellspacing="1" cellpadding="4"> <tr> <th colspan="2"> <?php echo $lang->get('acplm_th_lang_basic'); ?> </th> </tr> <tr> <td class="row2" style="width: 50%;"> <?php echo str_replace('"', '', $lang->get('acplm_field_lang_name_native')); ?> </td> <td class="row1"> <input type="text" name="lang_name_native" value="<?php echo htmlspecialchars($name_native); ?>" /> </td> </tr> <tr> <td class="row2"> <?php echo $lang->get('acplm_field_lang_name_english'); ?> </td> <td class="row1"> <input type="text" name="lang_name_english" value="<?php echo htmlspecialchars($name_english); ?>" /> </td> </tr> <tr> <td class="row2"> <?php echo $lang->get('acplm_field_lang_code') . '<br />' . '<small>' . $lang->get('acplm_field_lang_code_hint') . '</small>'; ?> </td> <td class="row1"> <?php echo $lang_code; ?> </td> </tr> <tr> <th class="subhead" colspan="2"> <button name="action" value="modify_language;finish=1;lang_id=<?php echo $lang_id; ?>"><?php echo $lang->get('etc_save_changes'); ?></button> </th> </tr> </table> </div> </form> <?php acp_start_form(); ?> <h3><?php echo $lang->get('acplm_heading_edit_strings_portal'); ?></h3> <p><?php echo $lang->get('acplm_msg_edit_strings_portal_intro'); ?></p> <p> <?php // Grab a Language object if ( $lang->lang_id == $lang_id ) { $lang_local =& $lang; } else { $lang_local = new Language($lang_id); $lang_local->fetch(); } $categories_loc = array(); // Using the & here ensures that a reference is created, thus avoiding wasting memory foreach ( $lang_local->strings as $cat => &$_ ) { unset($_); $categories_loc[$cat] = htmlspecialchars($lang->get("meta_$cat")); } asort($categories_loc); echo '<select name="cat_id">'; foreach ( $categories_loc as $cat_id => $cat_name) { echo "<option value=\"$cat_id\">$cat_name</option>"; } echo '</select>'; ?> <button name="action" value="edit_strings;lang_id=<?php echo $lang_id; ?>"> <?php echo $lang->get('acplm_btn_edit_strings_portal'); ?> </button> </p> <h3><?php echo $lang->get('acplm_heading_reimport_portal'); ?></h3> <p><?php echo $lang->get('acplm_msg_reimport_portal_intro'); ?></p> <p> <button name="action" value="reimport;iso639=<?php echo $lang_code; ?>;lang_id=<?php echo $lang_id; ?>"> <?php echo $lang->get('acplm_btn_reimport'); ?> </button> </p> </form> <?php echo '<h3>' . $lang->get('acplm_heading_backup') . '</h3>'; echo '<p>' . $lang->get('acplm_backup_intro') . '</p>'; echo '<form action="' . makeUrlNS('Admin', 'LangManager') . '" method="post">'; echo '<button name="action" value="backup_language;lang_id=' . $lang_id . '">' . $lang->get('acplm_btn_create_backup') . '</button>'; echo '</form>'; return true; case 'edit_strings': $cat_id = @$_POST['cat_id']; if ( !preg_match('/^[a-z0-9]+$/', $cat_id) || !is_int(@$parms['lang_id']) ) break; $lang_id =& $parms['lang_id']; if ( isset($parms['save']) && !defined('ENANO_DEMO_MODE') ) { // Grab a Language object if ( $lang->lang_id == $lang_id ) { $lang_local =& $lang; } else { $lang_local = new Language($lang_id); } // Main save loop // Trying to minimize queries as much as possible here, but you know how that goes. $count_upd = 0; foreach ( $_POST['string'] as $string_id => $user_content ) { $curr_content = $lang_local->get_uncensored("{$cat_id}_{$string_id}"); if ( $curr_content != $user_content ) { $count_upd++; $user_content = $db->escape($user_content); $string_id = $db->escape($string_id); $q = $db->sql_query('UPDATE ' . table_prefix . "language_strings SET string_content = '$user_content' WHERE lang_id = $lang_id AND string_category = '$cat_id' AND string_name = '$string_id';"); if ( !$q ) $db->_die(); } } if ( $count_upd > 0 ) { // Update the cache $lang_local->regen_caches(); // Update modification time $q = $db->sql_query('UPDATE ' . table_prefix . "language SET last_changed = " . time() . " WHERE lang_id = $lang_id;"); if ( !$q ) $db->_die(); } echo '<div class="info-box">' . $lang->get('acplm_msg_string_save_success') . '</div>'; } else if ( isset($parms['save']) && defined('ENANO_DEMO_MODE') ) { echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; } acp_start_form(); $cat_name = $lang->get("meta_$cat_id"); echo '<h3>' . $lang->get('acplm_editor_heading', array('cat_name' => $cat_name)) . '</h3>'; // Fetch all strings // This is more efficient than iterating through $lang->strings, I think. $q = $db->sql_query('SELECT string_id, string_name, string_content FROM ' . table_prefix . "language_strings WHERE string_category = '$cat_id' AND lang_id = $lang_id;"); if ( !$q ) $db->_die(); ?> <div class="tblholder"> <table border="0" cellspacing="1" cellpadding="4"> <tr> <th style="width: 3%;"><?php echo $lang->get('acplm_editor_col_string_name'); ?></th> <th><?php echo $lang->get('acplm_editor_col_string_content'); ?></th> </tr> <?php while ( $row = $db->fetchrow_num() ) { list($string_id, $string_name, $string_content) = $row; unset($row); echo '<tr>'; if ( strpos($string_content, "\n") ) { $editor = '<textarea rows="' . get_line_count($string_content) . '" cols="50" style="width: 99%;" '; $editor .= 'name="string[' . htmlspecialchars($string_name) . ']" '; $editor .= '>' . htmlspecialchars($string_content); $editor .= '</textarea>'; } else { $editor = '<input type="text" size="50" style="width: 99%;" '; $editor .= 'name="string[' . htmlspecialchars($string_name) . ']" '; $editor .= 'value="' . htmlspecialchars($string_content) . '" '; $editor .= '/>'; } echo '<td class="row2">' . htmlspecialchars($string_name) . '</td>'; echo '<td class="row1">' . $editor . '</td>'; echo '</tr>'; echo "\n"; } echo '<tr> <th class="subhead" colspan="2">'; echo '<input type="hidden" name="cat_id" value="' . $cat_id . '" />'; // Button: save echo '<button name="action" value="edit_strings;lang_id=' . $lang_id . ';save=1" style="font-weight: bold;">' . $lang->get('etc_save_changes') . '</button> '; // Button: revert echo '<button name="action" value="edit_strings;lang_id=' . $lang_id . '" style="font-weight: normal;">' . $lang->get('acplm_editor_btn_revert') . '</button> '; // Button: cancel echo '<button name="action" value="modify_language;lang_id=' . $lang_id . '" style="font-weight: normal;">' . $lang->get('acplm_editor_btn_cancel') . '</button>'; echo ' </th> </tr>'; ?> </table> </div> <?php echo '</form>'; return true; case 'reimport': if ( !isset($parms['iso639']) || !is_int(@$parms['lang_id']) ) break; if ( defined('ENANO_DEMO_MODE') ) { echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; break; } $lang_code =& $parms['iso639']; $lang_id =& $parms['lang_id']; $lang_list = list_available_languages(); if ( !isset($lang_list[$lang_code]) ) break; // Grab a Language object if ( $lang->lang_id == $lang_id ) { $lang_local =& $lang; } else { $lang_local = new Language($lang_id); } $lang_data =& $lang_list[$lang_code]; // This is the big re-import loop if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) { $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); } else { foreach ( array('core', 'admin', 'tools', 'user') as $file ) { $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); } } echo '<div class="info-box">' . $lang->get('acplm_msg_reimport_success') . '</div>'; break; case 'backup_language': if ( !is_int(@$parms['lang_id']) ) break; $lang_id =& $parms['lang_id']; // Grab a Language object if ( $lang->lang_id == $lang_id ) { $lang_local =& $lang; } else { $lang_local = new Language($lang_id); } $filename = 'enano_lang_' . $lang_local->lang_code . '_' . enano_date('ymd') . '.json'; // Free as much memory as possible $db->close(); unset($GLOBALS['session'], $GLOBALS['paths'], $GLOBALS['template'], $GLOBALS['plugins']); // HTTP headers header('Content-type: application/json'); header('Content-disposition: attachment; filename=' . $filename); // Export to JSON $lang_struct = array( 'categories' => array_keys($lang_local->strings), 'strings' => $lang_local->strings ); $lang_struct = enano_json_encode($lang_struct); header('Content-length: ' . strlen($lang_struct)); echo $lang_struct; exit; case 'uninstall_language': if ( !is_int(@$parms['lang_id']) ) break; if ( defined('ENANO_DEMO_MODE') ) { echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; break; } $lang_id =& $parms['lang_id']; if ( isset($parms['confirm']) ) { $lang_default = intval(getConfig('default_language')); if ( $lang_default == $lang_id ) { echo '<div class="error-box">' . $lang->get('acplm_err_cant_uninstall_default') . '</div>'; break; } if ( $lang_id == $lang->lang_id ) { // Unload the current language since it's about to be uninstalled unset($lang, $GLOBALS['lang']); $GLOBALS['lang'] = new Language($lang_default); global $lang; } // We're clear // Remove cache files $cache_file = ENANO_ROOT . "/cache/lang_{$lang_id}.php"; if ( file_exists($cache_file) ) @unlink($cache_file); $cache->purge("lang_{$lang_id}"); // Remove strings $q = $db->sql_query('DELETE FROM ' . table_prefix . "language_strings WHERE lang_id = $lang_id;"); if ( !$q ) $db->_die(); // Delete the language $q = $db->sql_query('DELETE FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); if ( !$q ) $db->_die(); echo '<div class="info-box">' . $lang->get('acplm_msg_uninstall_success') . '</div>'; break; } acp_start_form(); echo '<h3>' . $lang->get('acplm_uninstall_confirm_title') . '</h3>'; echo '<p>' . $lang->get('acplm_uninstall_confirm_body') . '</p>'; echo '<p><button name="action" style="font-weight: bold;" value="uninstall_language;lang_id=' . $lang_id . ';confirm=1">' . $lang->get('acplm_btn_uninstall_confirm') . '</button> '; echo '<button name="action" value="home">' . $lang->get('acplm_btn_uninstall_cancel') . '</button></p>'; echo '</form>'; return true; } } acp_start_form(); // Select current languages $q = $db->sql_query('SELECT lang_code, lang_name_native, lang_name_default, lang_id FROM ' . table_prefix . "language ORDER BY lang_id ASC;"); if ( !$q ) $db->_die(); // Language properties/edit/delete portal table echo '<h3>' . $lang->get('acplm_heading_editor_portal') . '</h3>'; echo '<div class="tblholder">'; echo '<table border="0" cellspacing="1" cellpadding="4">'; echo '<tr> <th>' . $lang->get('acplm_col_lang_id') . '</th> <th>' . $lang->get('acplm_col_lang_code') . '</th> <th>' . $lang->get('acplm_col_lang_name') . '</th> <th>' . $lang->get('acplm_col_lang_name_eng') . '</th> <th></th> </tr>'; $cls = 'row2'; $btn_edit = $lang->get('acplm_portal_btn_edit'); $btn_unin = $lang->get('acplm_portal_btn_unin'); while ( $row = $db->fetchrow($q) ) { $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; echo '<tr>'; $lang_code = htmlspecialchars($row['lang_code']); $lang_name_native = htmlspecialchars($row['lang_name_native']); $lang_name_english = htmlspecialchars($row['lang_name_default']); echo "<td class=\"$cls\" style=\"text-align: center;\">{$row['lang_id']}</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_code}</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_name_native}</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_name_english}</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\"><button name=\"action\" value=\"modify_language;lang_id={$row['lang_id']}\">$btn_edit</button> <button name=\"action\" value=\"uninstall_language;lang_id={$row['lang_id']}\">$btn_unin</button></td>"; echo '</tr>'; } echo '</table></div>'; // Reset the result pointer to zero so we can fetch that list of languages again if ( !$db->sql_data_seek(0, $q) ) { $db->_die('LangManager doing seek back to zero for installation blacklist'); } // $lang_list is fetched by the posthandler sometimes if ( !isset($lang_list) ) { // Build a list of languages in the languages/ directory, then // eliminate the ones that are already installed. $lang_list = list_available_languages(); } while ( $row = $db->fetchrow($q) ) { $lang_code =& $row['lang_code']; if ( isset($lang_list[$lang_code]) ) { unset($lang_list[$lang_code]); unset($lang_list[$lang_code]); // PHP <5.1.4 Zend bug } } if ( count($lang_list) > 0 ) { echo '<h3>' . $lang->get('acplm_heading_install') . '</h3>'; echo '<div class="tblholder"> <table border="0" cellspacing="1" cellpadding="4"> <tr> <th>' . $lang->get('acplm_col_lang_code') . '</th> <th>' . $lang->get('acplm_col_lang_name') . '</th> <th>' . $lang->get('acplm_col_lang_name_eng') . '</th> <th></th> </tr>'; $cls = 'row2'; foreach ( $lang_list as $lang_code => $lang_data ) { $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; echo '<tr>'; $lang_code = htmlspecialchars($lang_code); $lang_data['name'] = htmlspecialchars($lang_data['name']); $lang_data['name_eng'] = htmlspecialchars($lang_data['name_eng']); echo "<td class=\"$cls\" style=\"text-align: center;\">$lang_code</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_data['name']}</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_data['name_eng']}</td>"; echo "<td class=\"$cls\" style=\"text-align: center;\"><button name=\"action\" value=\"install_language;iso639=$lang_code\">" . $lang->get('acplm_btn_install_language') . "</button></td>"; echo '</tr>'; } echo ' </tr> </table> </div>'; } echo '</form>'; }