11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
12 */ |
12 */ |
13 |
13 |
14 function page_Admin_LangManager() |
14 function page_Admin_LangManager() |
15 { |
15 { |
16 global $db, $session, $paths, $template, $plugins; // Common objects |
16 global $db, $session, $paths, $template, $plugins; // Common objects |
17 global $lang; |
17 global $lang; |
18 global $cache; |
18 global $cache; |
19 if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) |
19 if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN ) |
20 { |
20 { |
21 $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); |
21 $login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true); |
22 echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>'; |
22 echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>'; |
23 echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>'; |
23 echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>'; |
24 return; |
24 return; |
25 } |
25 } |
26 if ( isset($_POST['action']) ) |
26 if ( isset($_POST['action']) ) |
27 { |
27 { |
28 $action =& $_POST['action']; |
28 $action =& $_POST['action']; |
29 // Parse parameters |
29 // Parse parameters |
30 if ( strpos($action, ';') ) |
30 if ( strpos($action, ';') ) |
31 { |
31 { |
32 // Parameter section |
32 // Parameter section |
33 $parms = substr($action, strpos($action, ';') + 1); |
33 $parms = substr($action, strpos($action, ';') + 1); |
34 |
34 |
35 // Action name section |
35 // Action name section |
36 $action = substr($action, 0, strpos($action, ';')); |
36 $action = substr($action, 0, strpos($action, ';')); |
37 |
37 |
38 // Match all parameters |
38 // Match all parameters |
39 preg_match_all('/([a-z0-9_]+)=(.+?)(;|$)/', $parms, $matches); |
39 preg_match_all('/([a-z0-9_]+)=(.+?)(;|$)/', $parms, $matches); |
40 $parms = array(); |
40 $parms = array(); |
41 |
41 |
42 // For each full parameter, assign $parms an associative value |
42 // For each full parameter, assign $parms an associative value |
43 foreach ( $matches[0] as $i => $_ ) |
43 foreach ( $matches[0] as $i => $_ ) |
44 { |
44 { |
45 $parm = $matches[2][$i]; |
45 $parm = $matches[2][$i]; |
46 |
46 |
47 // Is this parameter in the form of an integer? |
47 // Is this parameter in the form of an integer? |
48 // (designed to ease validation later) |
48 // (designed to ease validation later) |
49 if ( ctype_digit($parm) ) |
49 if ( ctype_digit($parm) ) |
50 // Yes, run intval(), this enabling is_int()-ish checks |
50 // Yes, run intval(), this enabling is_int()-ish checks |
51 $parm = intval($parm); |
51 $parm = intval($parm); |
52 |
52 |
53 $parms[$matches[1][$i]] = $parm; |
53 $parms[$matches[1][$i]] = $parm; |
54 } |
54 } |
55 } |
55 } |
56 switch ( $action ) |
56 switch ( $action ) |
57 { |
57 { |
58 case 'install_language': |
58 case 'install_language': |
59 |
59 |
60 if ( defined('ENANO_DEMO_MODE') ) |
60 if ( defined('ENANO_DEMO_MODE') ) |
61 { |
61 { |
62 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
62 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
63 break; |
63 break; |
64 } |
64 } |
65 |
65 |
66 $lang_list = list_available_languages(); |
66 $lang_list = list_available_languages(); |
67 // Verify that we have this language's metadata |
67 // Verify that we have this language's metadata |
68 if ( isset($lang_list[@$parms['iso639']]) ) |
68 if ( isset($lang_list[@$parms['iso639']]) ) |
69 { |
69 { |
70 // From here it's all downhill :-) |
70 // From here it's all downhill :-) |
71 $lang_code =& $parms['iso639']; |
71 $lang_code =& $parms['iso639']; |
72 $lang_data =& $lang_list[$lang_code]; |
72 $lang_data =& $lang_list[$lang_code]; |
73 |
73 |
74 $result = install_language($lang_code, $lang_data['name_eng'], $lang_data['name']); |
74 $result = install_language($lang_code, $lang_data['name_eng'], $lang_data['name']); |
75 if ( $result ) |
75 if ( $result ) |
76 { |
76 { |
77 // Language installed. Import the language files. |
77 // Language installed. Import the language files. |
78 $lang_local = new Language($lang_code); |
78 $lang_local = new Language($lang_code); |
79 if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) |
79 if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) |
80 { |
80 { |
81 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); |
81 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); |
82 } |
82 } |
83 else |
83 else |
84 { |
84 { |
85 foreach ( array('core', 'admin', 'tools', 'user') as $file ) |
85 foreach ( array('core', 'admin', 'tools', 'user') as $file ) |
86 { |
86 { |
87 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); |
87 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); |
88 } |
88 } |
89 } |
89 } |
90 unset($lang_local); |
90 unset($lang_local); |
91 |
91 |
92 echo '<div class="info-box">' . $lang->get('acplm_msg_lang_install_success', array('lang_name' => htmlspecialchars($lang_data['name_eng']))) . '</div>'; |
92 echo '<div class="info-box">' . $lang->get('acplm_msg_lang_install_success', array('lang_name' => htmlspecialchars($lang_data['name_eng']))) . '</div>'; |
93 } |
93 } |
94 } |
94 } |
95 break; |
95 break; |
96 case 'modify_language': |
96 case 'modify_language': |
97 |
97 |
98 $lang_id =& $parms['lang_id']; |
98 $lang_id =& $parms['lang_id']; |
99 if ( !is_int($lang_id) ) |
99 if ( !is_int($lang_id) ) |
100 { |
100 { |
101 echo 'Hacking attempt'; |
101 echo 'Hacking attempt'; |
102 break; |
102 break; |
103 } |
103 } |
104 |
104 |
105 if ( isset($parms['finish']) && !empty($_POST['lang_name_native']) && !empty($_POST['lang_name_english']) && !defined('ENANO_DEMO_MODE') ) |
105 if ( isset($parms['finish']) && !empty($_POST['lang_name_native']) && !empty($_POST['lang_name_english']) && !defined('ENANO_DEMO_MODE') ) |
106 { |
106 { |
107 // We just did validation above, it's safe to save. |
107 // We just did validation above, it's safe to save. |
108 $name_native = $db->escape($_POST['lang_name_native']); |
108 $name_native = $db->escape($_POST['lang_name_native']); |
109 $name_english = $db->escape($_POST['lang_name_english']); |
109 $name_english = $db->escape($_POST['lang_name_english']); |
110 |
110 |
111 $q = $db->sql_query('UPDATE ' . table_prefix . "language SET lang_name_native = '$name_native', lang_name_default = '$name_english' WHERE lang_id = $lang_id;"); |
111 $q = $db->sql_query('UPDATE ' . table_prefix . "language SET lang_name_native = '$name_native', lang_name_default = '$name_english' WHERE lang_id = $lang_id;"); |
112 if ( !$q ) |
112 if ( !$q ) |
113 $db->_die(); |
113 $db->_die(); |
114 |
114 |
115 echo '<div class="info-box">' . $lang->get('acplm_msg_basic_save_success') . '</div>'; |
115 echo '<div class="info-box">' . $lang->get('acplm_msg_basic_save_success') . '</div>'; |
116 } |
116 } |
117 else if ( isset($parms['finish']) && defined('ENANO_DEMO_MODE') ) |
117 else if ( isset($parms['finish']) && defined('ENANO_DEMO_MODE') ) |
118 { |
118 { |
119 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
119 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
120 } |
120 } |
121 |
121 |
122 // Select language data |
122 // Select language data |
123 $q = $db->sql_query('SELECT lang_name_native, lang_name_default, lang_code FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); |
123 $q = $db->sql_query('SELECT lang_name_native, lang_name_default, lang_code FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); |
124 if ( !$q ) |
124 if ( !$q ) |
125 $db->_die(); |
125 $db->_die(); |
126 |
126 |
127 list($name_native, $name_english, $lang_code) = $db->fetchrow_num(); |
127 list($name_native, $name_english, $lang_code) = $db->fetchrow_num(); |
128 |
128 |
129 // Output properties table |
129 // Output properties table |
130 echo '<h3>' . $lang->get('acplm_heading_modify') . '</h3>'; |
130 echo '<h3>' . $lang->get('acplm_heading_modify') . '</h3>'; |
131 |
131 |
132 acp_start_form(); |
132 acp_start_form(); |
133 |
133 |
134 ?> |
134 ?> |
135 <div class="tblholder"> |
135 <div class="tblholder"> |
136 <table border="0" cellspacing="1" cellpadding="4"> |
136 <table border="0" cellspacing="1" cellpadding="4"> |
137 <tr> |
137 <tr> |
138 <th colspan="2"> |
138 <th colspan="2"> |
139 <?php |
139 <?php |
140 echo $lang->get('acplm_th_lang_basic'); |
140 echo $lang->get('acplm_th_lang_basic'); |
141 ?> |
141 ?> |
142 </th> |
142 </th> |
143 </tr> |
143 </tr> |
144 <tr> |
144 <tr> |
145 <td class="row2" style="width: 50%;"> |
145 <td class="row2" style="width: 50%;"> |
146 <?php |
146 <?php |
147 echo str_replace('"', '', $lang->get('acplm_field_lang_name_native')); |
147 echo str_replace('"', '', $lang->get('acplm_field_lang_name_native')); |
148 ?> |
148 ?> |
149 </td> |
149 </td> |
150 <td class="row1"> |
150 <td class="row1"> |
151 <input type="text" name="lang_name_native" value="<?php echo htmlspecialchars($name_native); ?>" /> |
151 <input type="text" name="lang_name_native" value="<?php echo htmlspecialchars($name_native); ?>" /> |
152 </td> |
152 </td> |
153 </tr> |
153 </tr> |
154 <tr> |
154 <tr> |
155 <td class="row2"> |
155 <td class="row2"> |
156 <?php |
156 <?php |
157 echo $lang->get('acplm_field_lang_name_english'); |
157 echo $lang->get('acplm_field_lang_name_english'); |
158 ?> |
158 ?> |
159 </td> |
159 </td> |
160 <td class="row1"> |
160 <td class="row1"> |
161 <input type="text" name="lang_name_english" value="<?php echo htmlspecialchars($name_english); ?>" /> |
161 <input type="text" name="lang_name_english" value="<?php echo htmlspecialchars($name_english); ?>" /> |
162 </td> |
162 </td> |
163 </tr> |
163 </tr> |
164 <tr> |
164 <tr> |
165 <td class="row2"> |
165 <td class="row2"> |
166 <?php |
166 <?php |
167 echo $lang->get('acplm_field_lang_code') . '<br />' |
167 echo $lang->get('acplm_field_lang_code') . '<br />' |
168 . '<small>' . $lang->get('acplm_field_lang_code_hint') . '</small>'; |
168 . '<small>' . $lang->get('acplm_field_lang_code_hint') . '</small>'; |
169 ?> |
169 ?> |
170 </td> |
170 </td> |
171 <td class="row1"> |
171 <td class="row1"> |
172 <?php |
172 <?php |
173 echo $lang_code; |
173 echo $lang_code; |
174 ?> |
174 ?> |
175 </td> |
175 </td> |
176 </tr> |
176 </tr> |
177 <tr> |
177 <tr> |
178 <th class="subhead" colspan="2"> |
178 <th class="subhead" colspan="2"> |
179 <button name="action" value="modify_language;finish=1;lang_id=<?php echo $lang_id; ?>"><?php echo $lang->get('etc_save_changes'); ?></button> |
179 <button name="action" value="modify_language;finish=1;lang_id=<?php echo $lang_id; ?>"><?php echo $lang->get('etc_save_changes'); ?></button> |
180 </th> |
180 </th> |
181 </tr> |
181 </tr> |
182 </table> |
182 </table> |
183 </div> |
183 </div> |
184 </form> |
184 </form> |
185 |
185 |
186 <?php |
186 <?php |
187 acp_start_form(); |
187 acp_start_form(); |
188 ?> |
188 ?> |
189 |
189 |
190 <h3><?php echo $lang->get('acplm_heading_edit_strings_portal'); ?></h3> |
190 <h3><?php echo $lang->get('acplm_heading_edit_strings_portal'); ?></h3> |
191 <p><?php echo $lang->get('acplm_msg_edit_strings_portal_intro'); ?></p> |
191 <p><?php echo $lang->get('acplm_msg_edit_strings_portal_intro'); ?></p> |
192 |
192 |
193 <p> |
193 <p> |
194 |
194 |
195 <?php |
195 <?php |
196 |
196 |
197 // Grab a Language object |
197 // Grab a Language object |
198 if ( $lang->lang_id == $lang_id ) |
198 if ( $lang->lang_id == $lang_id ) |
199 { |
199 { |
200 $lang_local =& $lang; |
200 $lang_local =& $lang; |
201 } |
201 } |
202 else |
202 else |
203 { |
203 { |
204 $lang_local = new Language($lang_id); |
204 $lang_local = new Language($lang_id); |
205 $lang_local->fetch(); |
205 $lang_local->fetch(); |
206 } |
206 } |
207 |
207 |
208 $categories_loc = array(); |
208 $categories_loc = array(); |
209 |
209 |
210 // Using the & here ensures that a reference is created, thus avoiding wasting memory |
210 // Using the & here ensures that a reference is created, thus avoiding wasting memory |
211 foreach ( $lang_local->strings as $cat => &$_ ) |
211 foreach ( $lang_local->strings as $cat => &$_ ) |
212 { |
212 { |
213 unset($_); |
213 unset($_); |
214 $categories_loc[$cat] = htmlspecialchars($lang->get("meta_$cat")); |
214 $categories_loc[$cat] = htmlspecialchars($lang->get("meta_$cat")); |
215 } |
215 } |
216 |
216 |
217 asort($categories_loc); |
217 asort($categories_loc); |
218 |
218 |
219 echo '<select name="cat_id">'; |
219 echo '<select name="cat_id">'; |
220 foreach ( $categories_loc as $cat_id => $cat_name) |
220 foreach ( $categories_loc as $cat_id => $cat_name) |
221 { |
221 { |
222 echo "<option value=\"$cat_id\">$cat_name</option>"; |
222 echo "<option value=\"$cat_id\">$cat_name</option>"; |
223 } |
223 } |
224 echo '</select>'; |
224 echo '</select>'; |
225 |
225 |
226 ?> |
226 ?> |
227 <button name="action" value="edit_strings;lang_id=<?php echo $lang_id; ?>"> |
227 <button name="action" value="edit_strings;lang_id=<?php echo $lang_id; ?>"> |
228 <?php echo $lang->get('acplm_btn_edit_strings_portal'); ?> |
228 <?php echo $lang->get('acplm_btn_edit_strings_portal'); ?> |
229 </button> |
229 </button> |
230 </p> |
230 </p> |
231 |
231 |
232 <h3><?php echo $lang->get('acplm_heading_reimport_portal'); ?></h3> |
232 <h3><?php echo $lang->get('acplm_heading_reimport_portal'); ?></h3> |
233 <p><?php echo $lang->get('acplm_msg_reimport_portal_intro'); ?></p> |
233 <p><?php echo $lang->get('acplm_msg_reimport_portal_intro'); ?></p> |
234 |
234 |
235 <p> |
235 <p> |
236 <button name="action" value="reimport;iso639=<?php echo $lang_code; ?>;lang_id=<?php echo $lang_id; ?>"> |
236 <button name="action" value="reimport;iso639=<?php echo $lang_code; ?>;lang_id=<?php echo $lang_id; ?>"> |
237 <?php echo $lang->get('acplm_btn_reimport'); ?> |
237 <?php echo $lang->get('acplm_btn_reimport'); ?> |
238 </button> |
238 </button> |
239 </p> |
239 </p> |
240 |
240 |
241 </form> |
241 </form> |
242 |
242 |
243 <?php |
243 <?php |
244 |
244 |
245 echo '<h3>' . $lang->get('acplm_heading_backup') . '</h3>'; |
245 echo '<h3>' . $lang->get('acplm_heading_backup') . '</h3>'; |
246 echo '<p>' . $lang->get('acplm_backup_intro') . '</p>'; |
246 echo '<p>' . $lang->get('acplm_backup_intro') . '</p>'; |
247 |
247 |
248 echo '<form action="' . makeUrlNS('Admin', 'LangManager') . '" method="post">'; |
248 echo '<form action="' . makeUrlNS('Admin', 'LangManager') . '" method="post">'; |
249 echo '<button name="action" value="backup_language;lang_id=' . $lang_id . '">' . $lang->get('acplm_btn_create_backup') . '</button>'; |
249 echo '<button name="action" value="backup_language;lang_id=' . $lang_id . '">' . $lang->get('acplm_btn_create_backup') . '</button>'; |
250 echo '</form>'; |
250 echo '</form>'; |
251 |
251 |
252 return true; |
252 return true; |
253 case 'edit_strings': |
253 case 'edit_strings': |
254 |
254 |
255 $cat_id = @$_POST['cat_id']; |
255 $cat_id = @$_POST['cat_id']; |
256 if ( !preg_match('/^[a-z0-9]+$/', $cat_id) || !is_int(@$parms['lang_id']) ) |
256 if ( !preg_match('/^[a-z0-9]+$/', $cat_id) || !is_int(@$parms['lang_id']) ) |
257 break; |
257 break; |
258 |
258 |
259 $lang_id =& $parms['lang_id']; |
259 $lang_id =& $parms['lang_id']; |
260 |
260 |
261 if ( isset($parms['save']) && !defined('ENANO_DEMO_MODE') ) |
261 if ( isset($parms['save']) && !defined('ENANO_DEMO_MODE') ) |
262 { |
262 { |
263 // Grab a Language object |
263 // Grab a Language object |
264 if ( $lang->lang_id == $lang_id ) |
264 if ( $lang->lang_id == $lang_id ) |
265 { |
265 { |
266 $lang_local =& $lang; |
266 $lang_local =& $lang; |
267 } |
267 } |
268 else |
268 else |
269 { |
269 { |
270 $lang_local = new Language($lang_id); |
270 $lang_local = new Language($lang_id); |
271 } |
271 } |
272 // Main save loop |
272 // Main save loop |
273 // Trying to minimize queries as much as possible here, but you know how that goes. |
273 // Trying to minimize queries as much as possible here, but you know how that goes. |
274 $count_upd = 0; |
274 $count_upd = 0; |
275 foreach ( $_POST['string'] as $string_id => $user_content ) |
275 foreach ( $_POST['string'] as $string_id => $user_content ) |
276 { |
276 { |
277 $curr_content = $lang_local->get_uncensored("{$cat_id}_{$string_id}"); |
277 $curr_content = $lang_local->get_uncensored("{$cat_id}_{$string_id}"); |
278 if ( $curr_content != $user_content ) |
278 if ( $curr_content != $user_content ) |
279 { |
279 { |
280 $count_upd++; |
280 $count_upd++; |
281 $user_content = $db->escape($user_content); |
281 $user_content = $db->escape($user_content); |
282 $string_id = $db->escape($string_id); |
282 $string_id = $db->escape($string_id); |
283 $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';"); |
283 $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';"); |
284 if ( !$q ) |
284 if ( !$q ) |
285 $db->_die(); |
285 $db->_die(); |
286 } |
286 } |
287 } |
287 } |
288 if ( $count_upd > 0 ) |
288 if ( $count_upd > 0 ) |
289 { |
289 { |
290 // Update the cache |
290 // Update the cache |
291 $lang_local->regen_caches(); |
291 $lang_local->regen_caches(); |
292 |
292 |
293 // Update modification time |
293 // Update modification time |
294 $q = $db->sql_query('UPDATE ' . table_prefix . "language SET last_changed = " . time() . " WHERE lang_id = $lang_id;"); |
294 $q = $db->sql_query('UPDATE ' . table_prefix . "language SET last_changed = " . time() . " WHERE lang_id = $lang_id;"); |
295 if ( !$q ) |
295 if ( !$q ) |
296 $db->_die(); |
296 $db->_die(); |
297 } |
297 } |
298 |
298 |
299 echo '<div class="info-box">' . $lang->get('acplm_msg_string_save_success') . '</div>'; |
299 echo '<div class="info-box">' . $lang->get('acplm_msg_string_save_success') . '</div>'; |
300 } |
300 } |
301 else if ( isset($parms['save']) && defined('ENANO_DEMO_MODE') ) |
301 else if ( isset($parms['save']) && defined('ENANO_DEMO_MODE') ) |
302 { |
302 { |
303 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
303 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
304 } |
304 } |
305 |
305 |
306 acp_start_form(); |
306 acp_start_form(); |
307 |
307 |
308 $cat_name = $lang->get("meta_$cat_id"); |
308 $cat_name = $lang->get("meta_$cat_id"); |
309 echo '<h3>' . $lang->get('acplm_editor_heading', array('cat_name' => $cat_name)) . '</h3>'; |
309 echo '<h3>' . $lang->get('acplm_editor_heading', array('cat_name' => $cat_name)) . '</h3>'; |
310 |
310 |
311 // Fetch all strings |
311 // Fetch all strings |
312 // This is more efficient than iterating through $lang->strings, I think. |
312 // This is more efficient than iterating through $lang->strings, I think. |
313 $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;"); |
313 $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;"); |
314 if ( !$q ) |
314 if ( !$q ) |
315 $db->_die(); |
315 $db->_die(); |
316 |
316 |
317 ?> |
317 ?> |
318 <div class="tblholder"> |
318 <div class="tblholder"> |
319 <table border="0" cellspacing="1" cellpadding="4"> |
319 <table border="0" cellspacing="1" cellpadding="4"> |
320 <tr> |
320 <tr> |
321 <th style="width: 3%;"><?php echo $lang->get('acplm_editor_col_string_name'); ?></th> |
321 <th style="width: 3%;"><?php echo $lang->get('acplm_editor_col_string_name'); ?></th> |
322 <th><?php echo $lang->get('acplm_editor_col_string_content'); ?></th> |
322 <th><?php echo $lang->get('acplm_editor_col_string_content'); ?></th> |
323 </tr> |
323 </tr> |
324 <?php |
324 <?php |
325 |
325 |
326 while ( $row = $db->fetchrow_num() ) |
326 while ( $row = $db->fetchrow_num() ) |
327 { |
327 { |
328 list($string_id, $string_name, $string_content) = $row; |
328 list($string_id, $string_name, $string_content) = $row; |
329 unset($row); |
329 unset($row); |
330 |
330 |
331 echo '<tr>'; |
331 echo '<tr>'; |
332 |
332 |
333 if ( strpos($string_content, "\n") ) |
333 if ( strpos($string_content, "\n") ) |
334 { |
334 { |
335 $editor = '<textarea rows="' . get_line_count($string_content) . '" cols="50" style="width: 99%;" '; |
335 $editor = '<textarea rows="' . get_line_count($string_content) . '" cols="50" style="width: 99%;" '; |
336 $editor .= 'name="string[' . htmlspecialchars($string_name) . ']" '; |
336 $editor .= 'name="string[' . htmlspecialchars($string_name) . ']" '; |
337 $editor .= '>' . htmlspecialchars($string_content); |
337 $editor .= '>' . htmlspecialchars($string_content); |
338 $editor .= '</textarea>'; |
338 $editor .= '</textarea>'; |
339 } |
339 } |
340 else |
340 else |
341 { |
341 { |
342 $editor = '<input type="text" size="50" style="width: 99%;" '; |
342 $editor = '<input type="text" size="50" style="width: 99%;" '; |
343 $editor .= 'name="string[' . htmlspecialchars($string_name) . ']" '; |
343 $editor .= 'name="string[' . htmlspecialchars($string_name) . ']" '; |
344 $editor .= 'value="' . htmlspecialchars($string_content) . '" '; |
344 $editor .= 'value="' . htmlspecialchars($string_content) . '" '; |
345 $editor .= '/>'; |
345 $editor .= '/>'; |
346 } |
346 } |
347 |
347 |
348 echo '<td class="row2">' . htmlspecialchars($string_name) . '</td>'; |
348 echo '<td class="row2">' . htmlspecialchars($string_name) . '</td>'; |
349 echo '<td class="row1">' . $editor . '</td>'; |
349 echo '<td class="row1">' . $editor . '</td>'; |
350 |
350 |
351 |
351 |
352 echo '</tr>'; |
352 echo '</tr>'; |
353 echo "\n"; |
353 echo "\n"; |
354 } |
354 } |
355 |
355 |
356 echo '<tr> |
356 echo '<tr> |
357 <th class="subhead" colspan="2">'; |
357 <th class="subhead" colspan="2">'; |
358 |
358 |
359 echo '<input type="hidden" name="cat_id" value="' . $cat_id . '" />'; |
359 echo '<input type="hidden" name="cat_id" value="' . $cat_id . '" />'; |
360 |
360 |
361 // Button: save |
361 // Button: save |
362 echo '<button name="action" value="edit_strings;lang_id=' . $lang_id . ';save=1" style="font-weight: bold;">' . $lang->get('etc_save_changes') . '</button> '; |
362 echo '<button name="action" value="edit_strings;lang_id=' . $lang_id . ';save=1" style="font-weight: bold;">' . $lang->get('etc_save_changes') . '</button> '; |
363 // Button: revert |
363 // Button: revert |
364 echo '<button name="action" value="edit_strings;lang_id=' . $lang_id . '" style="font-weight: normal;">' . $lang->get('acplm_editor_btn_revert') . '</button> '; |
364 echo '<button name="action" value="edit_strings;lang_id=' . $lang_id . '" style="font-weight: normal;">' . $lang->get('acplm_editor_btn_revert') . '</button> '; |
365 // Button: cancel |
365 // Button: cancel |
366 echo '<button name="action" value="modify_language;lang_id=' . $lang_id . '" style="font-weight: normal;">' . $lang->get('acplm_editor_btn_cancel') . '</button>'; |
366 echo '<button name="action" value="modify_language;lang_id=' . $lang_id . '" style="font-weight: normal;">' . $lang->get('acplm_editor_btn_cancel') . '</button>'; |
367 |
367 |
368 echo ' </th> |
368 echo ' </th> |
369 </tr>'; |
369 </tr>'; |
370 |
370 |
371 ?> |
371 ?> |
372 </table> |
372 </table> |
373 </div> |
373 </div> |
374 <?php |
374 <?php |
375 echo '</form>'; |
375 echo '</form>'; |
376 |
376 |
377 return true; |
377 return true; |
378 case 'reimport': |
378 case 'reimport': |
379 if ( !isset($parms['iso639']) || !is_int(@$parms['lang_id']) ) |
379 if ( !isset($parms['iso639']) || !is_int(@$parms['lang_id']) ) |
380 break; |
380 break; |
381 |
381 |
382 if ( defined('ENANO_DEMO_MODE') ) |
382 if ( defined('ENANO_DEMO_MODE') ) |
383 { |
383 { |
384 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
384 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
385 break; |
385 break; |
386 } |
386 } |
387 |
387 |
388 $lang_code =& $parms['iso639']; |
388 $lang_code =& $parms['iso639']; |
389 $lang_id =& $parms['lang_id']; |
389 $lang_id =& $parms['lang_id']; |
390 |
390 |
391 $lang_list = list_available_languages(); |
391 $lang_list = list_available_languages(); |
392 |
392 |
393 if ( !isset($lang_list[$lang_code]) ) |
393 if ( !isset($lang_list[$lang_code]) ) |
394 break; |
394 break; |
395 |
395 |
396 // Grab a Language object |
396 // Grab a Language object |
397 if ( $lang->lang_id == $lang_id ) |
397 if ( $lang->lang_id == $lang_id ) |
398 { |
398 { |
399 $lang_local =& $lang; |
399 $lang_local =& $lang; |
400 } |
400 } |
401 else |
401 else |
402 { |
402 { |
403 $lang_local = new Language($lang_id); |
403 $lang_local = new Language($lang_id); |
404 } |
404 } |
405 |
405 |
406 $lang_data =& $lang_list[$lang_code]; |
406 $lang_data =& $lang_list[$lang_code]; |
407 |
407 |
408 // This is the big re-import loop |
408 // This is the big re-import loop |
409 if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) |
409 if ( file_exists(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json") ) |
410 { |
410 { |
411 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); |
411 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/backup.json"); |
412 } |
412 } |
413 else |
413 else |
414 { |
414 { |
415 foreach ( array('core', 'admin', 'tools', 'user') as $file ) |
415 foreach ( array('core', 'admin', 'tools', 'user') as $file ) |
416 { |
416 { |
417 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); |
417 $lang_local->import(ENANO_ROOT . "/language/{$lang_data['dir']}/$file.json"); |
418 } |
418 } |
419 } |
419 } |
420 |
420 |
421 echo '<div class="info-box">' . $lang->get('acplm_msg_reimport_success') . '</div>'; |
421 echo '<div class="info-box">' . $lang->get('acplm_msg_reimport_success') . '</div>'; |
422 |
422 |
423 break; |
423 break; |
424 case 'backup_language': |
424 case 'backup_language': |
425 if ( !is_int(@$parms['lang_id']) ) |
425 if ( !is_int(@$parms['lang_id']) ) |
426 break; |
426 break; |
427 |
427 |
428 $lang_id =& $parms['lang_id']; |
428 $lang_id =& $parms['lang_id']; |
429 |
429 |
430 // Grab a Language object |
430 // Grab a Language object |
431 if ( $lang->lang_id == $lang_id ) |
431 if ( $lang->lang_id == $lang_id ) |
432 { |
432 { |
433 $lang_local =& $lang; |
433 $lang_local =& $lang; |
434 } |
434 } |
435 else |
435 else |
436 { |
436 { |
437 $lang_local = new Language($lang_id); |
437 $lang_local = new Language($lang_id); |
438 } |
438 } |
439 |
439 |
440 $filename = 'enano_lang_' . $lang_local->lang_code . '_' . enano_date('ymd') . '.json'; |
440 $filename = 'enano_lang_' . $lang_local->lang_code . '_' . enano_date('ymd') . '.json'; |
441 |
441 |
442 // Free as much memory as possible |
442 // Free as much memory as possible |
443 $db->close(); |
443 $db->close(); |
444 unset($GLOBALS['session'], $GLOBALS['paths'], $GLOBALS['template'], $GLOBALS['plugins']); |
444 unset($GLOBALS['session'], $GLOBALS['paths'], $GLOBALS['template'], $GLOBALS['plugins']); |
445 |
445 |
446 // HTTP headers |
446 // HTTP headers |
447 header('Content-type: application/json'); |
447 header('Content-type: application/json'); |
448 header('Content-disposition: attachment; filename=' . $filename); |
448 header('Content-disposition: attachment; filename=' . $filename); |
449 |
449 |
450 // Export to JSON |
450 // Export to JSON |
451 $lang_struct = array( |
451 $lang_struct = array( |
452 'categories' => array_keys($lang_local->strings), |
452 'categories' => array_keys($lang_local->strings), |
453 'strings' => $lang_local->strings |
453 'strings' => $lang_local->strings |
454 ); |
454 ); |
455 |
455 |
456 $lang_struct = enano_json_encode($lang_struct); |
456 $lang_struct = enano_json_encode($lang_struct); |
457 |
457 |
458 header('Content-length: ' . strlen($lang_struct)); |
458 header('Content-length: ' . strlen($lang_struct)); |
459 echo $lang_struct; |
459 echo $lang_struct; |
460 |
460 |
461 exit; |
461 exit; |
462 |
462 |
463 case 'uninstall_language': |
463 case 'uninstall_language': |
464 if ( !is_int(@$parms['lang_id']) ) |
464 if ( !is_int(@$parms['lang_id']) ) |
465 break; |
465 break; |
466 |
466 |
467 if ( defined('ENANO_DEMO_MODE') ) |
467 if ( defined('ENANO_DEMO_MODE') ) |
468 { |
468 { |
469 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
469 echo '<div class="error-box">' . $lang->get('acplm_err_lang_install_demo') . '</div>'; |
470 break; |
470 break; |
471 } |
471 } |
472 |
472 |
473 $lang_id =& $parms['lang_id']; |
473 $lang_id =& $parms['lang_id']; |
474 |
474 |
475 if ( isset($parms['confirm']) ) |
475 if ( isset($parms['confirm']) ) |
476 { |
476 { |
477 $lang_default = intval(getConfig('default_language')); |
477 $lang_default = intval(getConfig('default_language')); |
478 if ( $lang_default == $lang_id ) |
478 if ( $lang_default == $lang_id ) |
479 { |
479 { |
480 echo '<div class="error-box">' . $lang->get('acplm_err_cant_uninstall_default') . '</div>'; |
480 echo '<div class="error-box">' . $lang->get('acplm_err_cant_uninstall_default') . '</div>'; |
481 break; |
481 break; |
482 } |
482 } |
483 if ( $lang_id == $lang->lang_id ) |
483 if ( $lang_id == $lang->lang_id ) |
484 { |
484 { |
485 // Unload the current language since it's about to be uninstalled |
485 // Unload the current language since it's about to be uninstalled |
486 unset($lang, $GLOBALS['lang']); |
486 unset($lang, $GLOBALS['lang']); |
487 $GLOBALS['lang'] = new Language($lang_default); |
487 $GLOBALS['lang'] = new Language($lang_default); |
488 global $lang; |
488 global $lang; |
489 } |
489 } |
490 // We're clear |
490 // We're clear |
491 |
491 |
492 // Remove cache files |
492 // Remove cache files |
493 $cache_file = ENANO_ROOT . "/cache/lang_{$lang_id}.php"; |
493 $cache_file = ENANO_ROOT . "/cache/lang_{$lang_id}.php"; |
494 if ( file_exists($cache_file) ) |
494 if ( file_exists($cache_file) ) |
495 @unlink($cache_file); |
495 @unlink($cache_file); |
496 |
496 |
497 $cache->purge("lang_{$lang_id}"); |
497 $cache->purge("lang_{$lang_id}"); |
498 |
498 |
499 // Remove strings |
499 // Remove strings |
500 $q = $db->sql_query('DELETE FROM ' . table_prefix . "language_strings WHERE lang_id = $lang_id;"); |
500 $q = $db->sql_query('DELETE FROM ' . table_prefix . "language_strings WHERE lang_id = $lang_id;"); |
501 if ( !$q ) |
501 if ( !$q ) |
502 $db->_die(); |
502 $db->_die(); |
503 |
503 |
504 // Delete the language |
504 // Delete the language |
505 $q = $db->sql_query('DELETE FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); |
505 $q = $db->sql_query('DELETE FROM ' . table_prefix . "language WHERE lang_id = $lang_id;"); |
506 if ( !$q ) |
506 if ( !$q ) |
507 $db->_die(); |
507 $db->_die(); |
508 |
508 |
509 echo '<div class="info-box">' . $lang->get('acplm_msg_uninstall_success') . '</div>'; |
509 echo '<div class="info-box">' . $lang->get('acplm_msg_uninstall_success') . '</div>'; |
510 break; |
510 break; |
511 } |
511 } |
512 |
512 |
513 acp_start_form(); |
513 acp_start_form(); |
514 |
514 |
515 echo '<h3>' . $lang->get('acplm_uninstall_confirm_title') . '</h3>'; |
515 echo '<h3>' . $lang->get('acplm_uninstall_confirm_title') . '</h3>'; |
516 echo '<p>' . $lang->get('acplm_uninstall_confirm_body') . '</p>'; |
516 echo '<p>' . $lang->get('acplm_uninstall_confirm_body') . '</p>'; |
517 |
517 |
518 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> '; |
518 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> '; |
519 echo '<button name="action" value="home">' . $lang->get('acplm_btn_uninstall_cancel') . '</button></p>'; |
519 echo '<button name="action" value="home">' . $lang->get('acplm_btn_uninstall_cancel') . '</button></p>'; |
520 |
520 |
521 echo '</form>'; |
521 echo '</form>'; |
522 return true; |
522 return true; |
523 } |
523 } |
524 } |
524 } |
525 |
525 |
526 acp_start_form(); |
526 acp_start_form(); |
527 |
527 |
528 // Select current languages |
528 // Select current languages |
529 $q = $db->sql_query('SELECT lang_code, lang_name_native, lang_name_default, lang_id FROM ' . table_prefix . "language ORDER BY lang_id ASC;"); |
529 $q = $db->sql_query('SELECT lang_code, lang_name_native, lang_name_default, lang_id FROM ' . table_prefix . "language ORDER BY lang_id ASC;"); |
530 if ( !$q ) |
530 if ( !$q ) |
531 $db->_die(); |
531 $db->_die(); |
532 |
532 |
533 // Language properties/edit/delete portal table |
533 // Language properties/edit/delete portal table |
534 echo '<h3>' . $lang->get('acplm_heading_editor_portal') . '</h3>'; |
534 echo '<h3>' . $lang->get('acplm_heading_editor_portal') . '</h3>'; |
535 |
535 |
536 echo '<div class="tblholder">'; |
536 echo '<div class="tblholder">'; |
537 echo '<table border="0" cellspacing="1" cellpadding="4">'; |
537 echo '<table border="0" cellspacing="1" cellpadding="4">'; |
538 echo '<tr> |
538 echo '<tr> |
539 <th>' . $lang->get('acplm_col_lang_id') . '</th> |
539 <th>' . $lang->get('acplm_col_lang_id') . '</th> |
540 <th>' . $lang->get('acplm_col_lang_code') . '</th> |
540 <th>' . $lang->get('acplm_col_lang_code') . '</th> |
541 <th>' . $lang->get('acplm_col_lang_name') . '</th> |
541 <th>' . $lang->get('acplm_col_lang_name') . '</th> |
542 <th>' . $lang->get('acplm_col_lang_name_eng') . '</th> |
542 <th>' . $lang->get('acplm_col_lang_name_eng') . '</th> |
543 <th></th> |
543 <th></th> |
544 </tr>'; |
544 </tr>'; |
545 |
545 |
546 $cls = 'row2'; |
546 $cls = 'row2'; |
547 |
547 |
548 $btn_edit = $lang->get('acplm_portal_btn_edit'); |
548 $btn_edit = $lang->get('acplm_portal_btn_edit'); |
549 $btn_unin = $lang->get('acplm_portal_btn_unin'); |
549 $btn_unin = $lang->get('acplm_portal_btn_unin'); |
550 |
550 |
551 while ( $row = $db->fetchrow($q) ) |
551 while ( $row = $db->fetchrow($q) ) |
552 { |
552 { |
553 $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; |
553 $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; |
554 |
554 |
555 echo '<tr>'; |
555 echo '<tr>'; |
556 |
556 |
557 $lang_code = htmlspecialchars($row['lang_code']); |
557 $lang_code = htmlspecialchars($row['lang_code']); |
558 $lang_name_native = htmlspecialchars($row['lang_name_native']); |
558 $lang_name_native = htmlspecialchars($row['lang_name_native']); |
559 $lang_name_english = htmlspecialchars($row['lang_name_default']); |
559 $lang_name_english = htmlspecialchars($row['lang_name_default']); |
560 |
560 |
561 echo "<td class=\"$cls\" style=\"text-align: center;\">{$row['lang_id']}</td>"; |
561 echo "<td class=\"$cls\" style=\"text-align: center;\">{$row['lang_id']}</td>"; |
562 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_code}</td>"; |
562 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_code}</td>"; |
563 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_name_native}</td>"; |
563 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_name_native}</td>"; |
564 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_name_english}</td>"; |
564 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_name_english}</td>"; |
565 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>"; |
565 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>"; |
566 |
566 |
567 echo '</tr>'; |
567 echo '</tr>'; |
568 } |
568 } |
569 |
569 |
570 echo '</table></div>'; |
570 echo '</table></div>'; |
571 |
571 |
572 // Reset the result pointer to zero so we can fetch that list of languages again |
572 // Reset the result pointer to zero so we can fetch that list of languages again |
573 if ( !$db->sql_data_seek(0, $q) ) |
573 if ( !$db->sql_data_seek(0, $q) ) |
574 { |
574 { |
575 $db->_die('LangManager doing seek back to zero for installation blacklist'); |
575 $db->_die('LangManager doing seek back to zero for installation blacklist'); |
576 } |
576 } |
577 |
577 |
578 // $lang_list is fetched by the posthandler sometimes |
578 // $lang_list is fetched by the posthandler sometimes |
579 if ( !isset($lang_list) ) |
579 if ( !isset($lang_list) ) |
580 { |
580 { |
581 // Build a list of languages in the languages/ directory, then |
581 // Build a list of languages in the languages/ directory, then |
582 // eliminate the ones that are already installed. |
582 // eliminate the ones that are already installed. |
583 $lang_list = list_available_languages(); |
583 $lang_list = list_available_languages(); |
584 } |
584 } |
585 |
585 |
586 while ( $row = $db->fetchrow($q) ) |
586 while ( $row = $db->fetchrow($q) ) |
587 { |
587 { |
588 $lang_code =& $row['lang_code']; |
588 $lang_code =& $row['lang_code']; |
589 if ( isset($lang_list[$lang_code]) ) |
589 if ( isset($lang_list[$lang_code]) ) |
590 { |
590 { |
591 unset($lang_list[$lang_code]); |
591 unset($lang_list[$lang_code]); |
592 unset($lang_list[$lang_code]); // PHP <5.1.4 Zend bug |
592 unset($lang_list[$lang_code]); // PHP <5.1.4 Zend bug |
593 } |
593 } |
594 } |
594 } |
595 |
595 |
596 if ( count($lang_list) > 0 ) |
596 if ( count($lang_list) > 0 ) |
597 { |
597 { |
598 echo '<h3>' . $lang->get('acplm_heading_install') . '</h3>'; |
598 echo '<h3>' . $lang->get('acplm_heading_install') . '</h3>'; |
599 echo '<div class="tblholder"> |
599 echo '<div class="tblholder"> |
600 <table border="0" cellspacing="1" cellpadding="4"> |
600 <table border="0" cellspacing="1" cellpadding="4"> |
601 <tr> |
601 <tr> |
602 <th>' . $lang->get('acplm_col_lang_code') . '</th> |
602 <th>' . $lang->get('acplm_col_lang_code') . '</th> |
603 <th>' . $lang->get('acplm_col_lang_name') . '</th> |
603 <th>' . $lang->get('acplm_col_lang_name') . '</th> |
604 <th>' . $lang->get('acplm_col_lang_name_eng') . '</th> |
604 <th>' . $lang->get('acplm_col_lang_name_eng') . '</th> |
605 <th></th> |
605 <th></th> |
606 </tr>'; |
606 </tr>'; |
607 |
607 |
608 $cls = 'row2'; |
608 $cls = 'row2'; |
609 foreach ( $lang_list as $lang_code => $lang_data ) |
609 foreach ( $lang_list as $lang_code => $lang_data ) |
610 { |
610 { |
611 $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; |
611 $cls = ( $cls == 'row1' ) ? 'row2' : 'row1'; |
612 |
612 |
613 echo '<tr>'; |
613 echo '<tr>'; |
614 |
614 |
615 $lang_code = htmlspecialchars($lang_code); |
615 $lang_code = htmlspecialchars($lang_code); |
616 $lang_data['name'] = htmlspecialchars($lang_data['name']); |
616 $lang_data['name'] = htmlspecialchars($lang_data['name']); |
617 $lang_data['name_eng'] = htmlspecialchars($lang_data['name_eng']); |
617 $lang_data['name_eng'] = htmlspecialchars($lang_data['name_eng']); |
618 |
618 |
619 echo "<td class=\"$cls\" style=\"text-align: center;\">$lang_code</td>"; |
619 echo "<td class=\"$cls\" style=\"text-align: center;\">$lang_code</td>"; |
620 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_data['name']}</td>"; |
620 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_data['name']}</td>"; |
621 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_data['name_eng']}</td>"; |
621 echo "<td class=\"$cls\" style=\"text-align: center;\">{$lang_data['name_eng']}</td>"; |
622 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>"; |
622 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>"; |
623 |
623 |
624 echo '</tr>'; |
624 echo '</tr>'; |
625 } |
625 } |
626 echo ' </tr> |
626 echo ' </tr> |
627 </table> |
627 </table> |
628 </div>'; |
628 </div>'; |
629 } |
629 } |
630 echo '</form>'; |
630 echo '</form>'; |
631 } |
631 } |
632 |
632 |