Verzeichnisstruktur phpBB-3.0.0
- Veröffentlicht
- 12.12.2007
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
acp_board.php
001 <?php
002 /**
003 *
004 * @package acp
005 * @version $Id$
006 * @copyright (c) 2005 phpBB Group
007 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
008 *
009 * @todo add cron intervals to server settings? (database_gc, queue_interval, session_gc, search_gc, cache_gc, warnings_gc)
010 */
011
012 /**
013 * @ignore
014 */
015 if (!defined('IN_PHPBB'))
016 {
017 exit;
018 }
019
020 /**
021 * @package acp
022 */
023 class acp_board
024 {
025 var $u_action;
026 var $new_config = array();
027
028 function main($id, $mode)
029 {
030 global $db, $user, $auth, $template;
031 global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
032
033 $user->add_lang('acp/board');
034
035 $action = request_var('action', '');
036 $submit = (isset($_POST['submit'])) ? true : false;
037
038 $form_key = 'acp_board';
039 add_form_key($form_key);
040
041 /**
042 * Validation types are:
043 * string, int, bool,
044 * script_path (absolute path in url - beginning with / and no trailing slash),
045 * rpath (relative), rwpath (realtive, writable), path (relative path, but able to escape the root), wpath (writable)
046 */
047 switch ($mode)
048 {
049 case 'settings':
050 $display_vars = array(
051 'title' => 'ACP_BOARD_SETTINGS',
052 'vars' => array(
053 'legend1' => 'ACP_BOARD_SETTINGS',
054 'sitename' => array('lang' => 'SITE_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
055 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false),
056 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true),
057 'board_disable_msg' => false,
058 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false),
059 'default_dateformat' => array('lang' => 'DEFAULT_DATE_FORMAT', 'validate' => 'string', 'type' => 'custom', 'method' => 'dateformat_select', 'explain' => true),
060 'board_timezone' => array('lang' => 'SYSTEM_TIMEZONE', 'validate' => 'string', 'type' => 'select', 'function' => 'tz_select', 'params' => array('{CONFIG_VALUE}', 1), 'explain' => false),
061 'board_dst' => array('lang' => 'SYSTEM_DST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
062 'default_style' => array('lang' => 'DEFAULT_STYLE', 'validate' => 'int', 'type' => 'select', 'function' => 'style_select', 'params' => array('{CONFIG_VALUE}', false), 'explain' => false),
063 'override_user_style' => array('lang' => 'OVERRIDE_STYLE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
064
065 'legend2' => 'WARNINGS',
066 'warnings_expire_days' => array('lang' => 'WARNINGS_EXPIRE', 'validate' => 'int', 'type' => 'text:3:4', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
067 )
068 );
069 break;
070
071 case 'features':
072 $display_vars = array(
073 'title' => 'ACP_BOARD_FEATURES',
074 'vars' => array(
075 'legend1' => 'ACP_BOARD_FEATURES',
076 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
077 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
078 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
079 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
080 'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
081 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
082 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
083 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
084 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
085 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
086 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
087 'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
088
089 'legend2' => 'ACP_LOAD_SETTINGS',
090 'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
091 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
092 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
093 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
094 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
095 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
096 )
097 );
098 break;
099
100 case 'avatar':
101 $display_vars = array(
102 'title' => 'ACP_AVATAR_SETTINGS',
103 'vars' => array(
104 'legend1' => 'ACP_AVATAR_SETTINGS',
105 'avatar_min_height' => false, 'avatar_min_width' => false, 'avatar_max_height' => false, 'avatar_max_width' => false,
106
107 'allow_avatar_local' => array('lang' => 'ALLOW_LOCAL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
108 'allow_avatar_remote' => array('lang' => 'ALLOW_REMOTE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
109 'allow_avatar_upload' => array('lang' => 'ALLOW_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
110 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int', 'type' => 'text:4:10', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
111 'avatar_min' => array('lang' => 'MIN_AVATAR_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
112 'avatar_max' => array('lang' => 'MAX_AVATAR_SIZE', 'validate' => 'int', 'type' => 'dimension:3:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
113 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true),
114 'avatar_gallery_path' => array('lang' => 'AVATAR_GALLERY_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true)
115 )
116 );
117 break;
118
119 case 'message':
120 $display_vars = array(
121 'title' => 'ACP_MESSAGE_SETTINGS',
122 'lang' => 'ucp',
123 'vars' => array(
124 'legend1' => 'GENERAL_SETTINGS',
125 'allow_privmsg' => array('lang' => 'BOARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
126 'pm_max_boxes' => array('lang' => 'BOXES_MAX', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true),
127 'pm_max_msgs' => array('lang' => 'BOXES_LIMIT', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true),
128 'full_folder_action' => array('lang' => 'FULL_FOLDER_ACTION', 'validate' => 'int', 'type' => 'select', 'method' => 'full_folder_select', 'explain' => true),
129 'pm_edit_time' => array('lang' => 'PM_EDIT_TIME', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
130
131 'legend2' => 'GENERAL_OPTIONS',
132 'allow_mass_pm' => array('lang' => 'ALLOW_MASS_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
133 'auth_bbcode_pm' => array('lang' => 'ALLOW_BBCODE_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
134 'auth_smilies_pm' => array('lang' => 'ALLOW_SMILIES_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
135 'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
136 'allow_sig_pm' => array('lang' => 'ALLOW_SIG_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
137 'print_pm' => array('lang' => 'ALLOW_PRINT_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
138 'forward_pm' => array('lang' => 'ALLOW_FORWARD_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
139 'auth_img_pm' => array('lang' => 'ALLOW_IMG_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
140 'auth_flash_pm' => array('lang' => 'ALLOW_FLASH_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
141 'enable_pm_icons' => array('lang' => 'ENABLE_PM_ICONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false)
142 )
143 );
144 break;
145
146 case 'post':
147 $display_vars = array(
148 'title' => 'ACP_POST_SETTINGS',
149 'vars' => array(
150 'legend1' => 'GENERAL_OPTIONS',
151 'allow_topic_notify' => array('lang' => 'ALLOW_TOPIC_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
152 'allow_forum_notify' => array('lang' => 'ALLOW_FORUM_NOTIFY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
153 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
154 'allow_post_flash' => array('lang' => 'ALLOW_POST_FLASH', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
155 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
156 'allow_post_links' => array('lang' => 'ALLOW_POST_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
157 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
158 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
159 'enable_post_confirm' => array('lang' => 'VISUAL_CONFIRM_POST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
160
161 'legend2' => 'POSTING',
162 'bump_type' => false,
163 'edit_time' => array('lang' => 'EDIT_TIME', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
164 'display_last_edited' => array('lang' => 'DISPLAY_LAST_EDITED', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
165 'flood_interval' => array('lang' => 'FLOOD_INTERVAL', 'validate' => 'int', 'type' => 'text:3:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
166 'bump_interval' => array('lang' => 'BUMP_INTERVAL', 'validate' => 'int', 'type' => 'custom', 'method' => 'bump_interval', 'explain' => true),
167 'topics_per_page' => array('lang' => 'TOPICS_PER_PAGE', 'validate' => 'int', 'type' => 'text:3:4', 'explain' => false),
168 'posts_per_page' => array('lang' => 'POSTS_PER_PAGE', 'validate' => 'int', 'type' => 'text:3:4', 'explain' => false),
169 'hot_threshold' => array('lang' => 'HOT_THRESHOLD', 'validate' => 'int', 'type' => 'text:3:4', 'explain' => true),
170 'max_poll_options' => array('lang' => 'MAX_POLL_OPTIONS', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => false),
171 'max_post_chars' => array('lang' => 'CHAR_LIMIT', 'validate' => 'int', 'type' => 'text:4:6', 'explain' => true),
172 'max_post_smilies' => array('lang' => 'SMILIES_LIMIT', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true),
173 'max_post_urls' => array('lang' => 'MAX_POST_URLS', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true),
174 'max_post_font_size' => array('lang' => 'MAX_POST_FONT_SIZE', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'),
175 'max_quote_depth' => array('lang' => 'QUOTE_DEPTH_LIMIT', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true),
176 'max_post_img_width' => array('lang' => 'MAX_POST_IMG_WIDTH', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
177 'max_post_img_height' => array('lang' => 'MAX_POST_IMG_HEIGHT', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
178 )
179 );
180 break;
181
182 case 'signature':
183 $display_vars = array(
184 'title' => 'ACP_SIGNATURE_SETTINGS',
185 'vars' => array(
186 'legend1' => 'GENERAL_OPTIONS',
187 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
188 'allow_sig_bbcode' => array('lang' => 'ALLOW_SIG_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
189 'allow_sig_img' => array('lang' => 'ALLOW_SIG_IMG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
190 'allow_sig_flash' => array('lang' => 'ALLOW_SIG_FLASH', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
191 'allow_sig_smilies' => array('lang' => 'ALLOW_SIG_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
192 'allow_sig_links' => array('lang' => 'ALLOW_SIG_LINKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
193
194 'legend2' => 'GENERAL_SETTINGS',
195 'max_sig_chars' => array('lang' => 'MAX_SIG_LENGTH', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true),
196 'max_sig_urls' => array('lang' => 'MAX_SIG_URLS', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true),
197 'max_sig_font_size' => array('lang' => 'MAX_SIG_FONT_SIZE', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true, 'append' => ' %'),
198 'max_sig_smilies' => array('lang' => 'MAX_SIG_SMILIES', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true),
199 'max_sig_img_width' => array('lang' => 'MAX_SIG_IMG_WIDTH', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
200 'max_sig_img_height' => array('lang' => 'MAX_SIG_IMG_HEIGHT', 'validate' => 'int', 'type' => 'text:5:4', 'explain' => true, 'append' => ' ' . $user->lang['PIXEL']),
201 )
202 );
203 break;
204
205 case 'registration':
206 $display_vars = array(
207 'title' => 'ACP_REGISTER_SETTINGS',
208 'vars' => array(
209 'legend1' => 'GENERAL_SETTINGS',
210 'max_name_chars' => false,
211 'max_pass_chars' => false,
212
213 'require_activation' => array('lang' => 'ACC_ACTIVATION', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_acc_activation', 'explain' => true),
214 'min_name_chars' => array('lang' => 'USERNAME_LENGTH', 'validate' => 'int', 'type' => 'custom', 'method' => 'username_length', 'explain' => true),
215 'min_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int', 'type' => 'custom', 'method' => 'password_length', 'explain' => true),
216 'allow_name_chars' => array('lang' => 'USERNAME_CHARS', 'validate' => 'string', 'type' => 'select', 'method' => 'select_username_chars', 'explain' => true),
217 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
218 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
219
220 'legend2' => 'GENERAL_OPTIONS',
221 'allow_namechange' => array('lang' => 'ALLOW_NAME_CHANGE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
222 'allow_emailreuse' => array('lang' => 'ALLOW_EMAIL_REUSE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
223 'enable_confirm' => array('lang' => 'VISUAL_CONFIRM_REG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
224 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true),
225 'max_reg_attempts' => array('lang' => 'REG_LIMIT', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true),
226 'min_time_reg' => array('lang' => 'MIN_TIME_REG', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
227 'min_time_terms' => array('lang' => 'MIN_TIME_TERMS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
228
229 'legend3' => 'COPPA',
230 'coppa_enable' => array('lang' => 'ENABLE_COPPA', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
231 'coppa_mail' => array('lang' => 'COPPA_MAIL', 'validate' => 'string', 'type' => 'textarea:5:40', 'explain' => true),
232 'coppa_fax' => array('lang' => 'COPPA_FAX', 'validate' => 'string', 'type' => 'text:25:100', 'explain' => false),
233 )
234 );
235 break;
236
237 case 'cookie':
238 $display_vars = array(
239 'title' => 'ACP_COOKIE_SETTINGS',
240 'vars' => array(
241 'legend1' => 'ACP_COOKIE_SETTINGS',
242 'cookie_domain' => array('lang' => 'COOKIE_DOMAIN', 'validate' => 'string', 'type' => 'text::255', 'explain' => false),
243 'cookie_name' => array('lang' => 'COOKIE_NAME', 'validate' => 'string', 'type' => 'text::16', 'explain' => false),
244 'cookie_path' => array('lang' => 'COOKIE_PATH', 'validate' => 'string', 'type' => 'text::255', 'explain' => false),
245 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'validate' => 'bool', 'type' => 'radio:disabled_enabled', 'explain' => true)
246 )
247 );
248 break;
249
250 case 'load':
251 $display_vars = array(
252 'title' => 'ACP_LOAD_SETTINGS',
253 'vars' => array(
254 'legend1' => 'GENERAL_SETTINGS',
255 'limit_load' => array('lang' => 'LIMIT_LOAD', 'validate' => 'string', 'type' => 'text:4:4', 'explain' => true),
256 'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int', 'type' => 'text:5:10', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
257 'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int', 'type' => 'text:4:4', 'explain' => true),
258 'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int', 'type' => 'text:4:3', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']),
259
260 'legend2' => 'GENERAL_OPTIONS',
261 'load_db_track' => array('lang' => 'YES_POST_MARKING', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
262 'load_db_lastread' => array('lang' => 'YES_READ_MARKING', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
263 'load_anon_lastread' => array('lang' => 'YES_ANON_READ_MARKING', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
264 'load_online' => array('lang' => 'YES_ONLINE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
265 'load_online_guests' => array('lang' => 'YES_ONLINE_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
266 'load_onlinetrack' => array('lang' => 'YES_ONLINE_TRACK', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
267 'load_birthdays' => array('lang' => 'YES_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
268 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
269 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
270 'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
271 'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
272
273 'legend3' => 'CUSTOM_PROFILE_FIELDS',
274 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
275 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
276 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
277 )
278 );
279 break;
280
281 case 'auth':
282 $display_vars = array(
283 'title' => 'ACP_AUTH_SETTINGS',
284 'vars' => array(
285 'legend1' => 'ACP_AUTH_SETTINGS',
286 'auth_method' => array('lang' => 'AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'select_auth_method', 'explain' => false)
287 )
288 );
289 break;
290
291 case 'server':
292 $display_vars = array(
293 'title' => 'ACP_SERVER_SETTINGS',
294 'vars' => array(
295 'legend1' => 'ACP_SERVER_SETTINGS',
296 'gzip_compress' => array('lang' => 'ENABLE_GZIP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
297
298 'legend2' => 'PATH_SETTINGS',
299 'smilies_path' => array('lang' => 'SMILIES_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
300 'icons_path' => array('lang' => 'ICONS_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
301 'upload_icons_path' => array('lang' => 'UPLOAD_ICONS_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
302 'ranks_path' => array('lang' => 'RANKS_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
303
304 'legend3' => 'SERVER_URL_SETTINGS',
305 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
306 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'validate' => 'string', 'type' => 'text:10:10', 'explain' => true),
307 'server_name' => array('lang' => 'SERVER_NAME', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true),
308 'server_port' => array('lang' => 'SERVER_PORT', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true),
309 'script_path' => array('lang' => 'SCRIPT_PATH', 'validate' => 'script_path', 'type' => 'text::255', 'explain' => true),
310 )
311 );
312 break;
313
314 case 'security':
315 $display_vars = array(
316 'title' => 'ACP_SECURITY_SETTINGS',
317 'vars' => array(
318 'legend1' => 'ACP_SECURITY_SETTINGS',
319 'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
320 'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
321 'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true),
322 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
323 'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
324 'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
325 'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
326 'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
327 'chg_passforce' => array('lang' => 'FORCE_PASS_CHANGE', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']),
328 'max_login_attempts' => array('lang' => 'MAX_LOGIN_ATTEMPTS', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true),
329 'tpl_allow_php' => array('lang' => 'TPL_ALLOW_PHP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
330 'form_token_lifetime' => array('lang' => 'FORM_TIME_MAX', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
331 'form_token_mintime' => array('lang' => 'FORM_TIME_MIN', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']),
332 'form_token_sid_guests' => array('lang' => 'FORM_SID_GUESTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
333
334 )
335 );
336 break;
337
338 case 'email':
339 $display_vars = array(
340 'title' => 'ACP_EMAIL_SETTINGS',
341 'vars' => array(
342 'legend1' => 'GENERAL_SETTINGS',
343 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
344 'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true),
345 'email_function_name' => array('lang' => 'EMAIL_FUNCTION_NAME', 'validate' => 'string', 'type' => 'text:20:50', 'explain' => true),
346 'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int', 'type' => 'text:5:5', 'explain' => true),
347 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'string', 'type' => 'text:25:100', 'explain' => true),
348 'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'string', 'type' => 'text:25:100', 'explain' => true),
349 'board_email_sig' => array('lang' => 'EMAIL_SIG', 'validate' => 'string', 'type' => 'textarea:5:30', 'explain' => true),
350 'board_hide_emails' => array('lang' => 'BOARD_HIDE_EMAILS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
351
352 'legend2' => 'SMTP_SETTINGS',
353 'smtp_delivery' => array('lang' => 'USE_SMTP', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
354 'smtp_host' => array('lang' => 'SMTP_SERVER', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => false),
355 'smtp_port' => array('lang' => 'SMTP_PORT', 'validate' => 'int', 'type' => 'text:4:5', 'explain' => true),
356 'smtp_auth_method' => array('lang' => 'SMTP_AUTH_METHOD', 'validate' => 'string', 'type' => 'select', 'method' => 'mail_auth_select', 'explain' => true),
357 'smtp_username' => array('lang' => 'SMTP_USERNAME', 'validate' => 'string', 'type' => 'text:25:255', 'explain' => true),
358 'smtp_password' => array('lang' => 'SMTP_PASSWORD', 'validate' => 'string', 'type' => 'password:25:255', 'explain' => true)
359 )
360 );
361 break;
362
363 default:
364 trigger_error('NO_MODE', E_USER_ERROR);
365 break;
366 }
367
368 if (isset($display_vars['lang']))
369 {
370 $user->add_lang($display_vars['lang']);
371 }
372
373 $this->new_config = $config;
374 $cfg_array = (isset($_REQUEST['config'])) ? utf8_normalize_nfc(request_var('config', array('' => ''), true)) : $this->new_config;
375 $error = array();
376
377 // We validate the complete config if whished
378 validate_config_vars($display_vars['vars'], $cfg_array, $error);
379
380 if ($submit && !check_form_key($form_key))
381 {
382 $error[] = $user->lang['FORM_INVALID'];
383 }
384 // Do not write values if there is an error
385 if (sizeof($error))
386 {
387 $submit = false;
388 }
389
390 // We go through the display_vars to make sure no one is trying to set variables he/she is not allowed to...
391 foreach ($display_vars['vars'] as $config_name => $null)
392 {
393 if (!isset($cfg_array[$config_name]) || strpos($config_name, 'legend') !== false)
394 {
395 continue;
396 }
397
398 if ($config_name == 'auth_method')
399 {
400 continue;
401 }
402
403 $this->new_config[$config_name] = $config_value = $cfg_array[$config_name];
404
405 if ($config_name == 'email_function_name')
406 {
407 $this->new_config['email_function_name'] = trim(str_replace(array('(', ')'), array('', ''), $this->new_config['email_function_name']));
408 $this->new_config['email_function_name'] = (empty($this->new_config['email_function_name']) || !function_exists($this->new_config['email_function_name'])) ? 'mail' : $this->new_config['email_function_name'];
409 $config_value = $this->new_config['email_function_name'];
410 }
411
412 if ($submit)
413 {
414 set_config($config_name, $config_value);
415 }
416 }
417
418 if ($mode == 'auth')
419 {
420 // Retrieve a list of auth plugins and check their config values
421 $auth_plugins = array();
422
423 $dp = @opendir($phpbb_root_path . 'includes/auth');
424
425 if ($dp)
426 {
427 while (($file = readdir($dp)) !== false)
428 {
429 if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file))
430 {
431 $auth_plugins[] = basename(preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file));
432 }
433 }
434 closedir($dp);
435
436 sort($auth_plugins);
437 }
438
439 $updated_auth_settings = false;
440 $old_auth_config = array();
441 foreach ($auth_plugins as $method)
442 {
443 if ($method && file_exists($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx))
444 {
445 include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
446
447 $method = 'acp_' . $method;
448 if (function_exists($method))
449 {
450 if ($fields = $method($this->new_config))
451 {
452 // Check if we need to create config fields for this plugin and save config when submit was pressed
453 foreach ($fields['config'] as $field)
454 {
455 if (!isset($config[$field]))
456 {
457 set_config($field, '');
458 }
459
460 if (!isset($cfg_array[$field]) || strpos($field, 'legend') !== false)
461 {
462 continue;
463 }
464
465 $old_auth_config[$field] = $this->new_config[$field];
466 $config_value = $cfg_array[$field];
467 $this->new_config[$field] = $config_value;
468
469 if ($submit)
470 {
471 $updated_auth_settings = true;
472 set_config($field, $config_value);
473 }
474 }
475 }
476 unset($fields);
477 }
478 }
479 }
480
481 if ($submit && (($cfg_array['auth_method'] != $this->new_config['auth_method']) || $updated_auth_settings))
482 {
483 $method = basename($cfg_array['auth_method']);
484 if ($method && in_array($method, $auth_plugins))
485 {
486 include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
487
488 $method = 'init_' . $method;
489 if (function_exists($method))
490 {
491 if ($error = $method())
492 {
493 foreach ($old_auth_config as $config_name => $config_value)
494 {
495 set_config($config_name, $config_value);
496 }
497 trigger_error($error . adm_back_link($this->u_action), E_USER_WARNING);
498 }
499 }
500 set_config('auth_method', basename($cfg_array['auth_method']));
501 }
502 else
503 {
504 trigger_error('NO_AUTH_PLUGIN', E_USER_ERROR);
505 }
506 }
507 }
508
509 if ($submit)
510 {
511 add_log('admin', 'LOG_CONFIG_' . strtoupper($mode));
512
513 trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
514 }
515
516 $this->tpl_name = 'acp_board';
517 $this->page_title = $display_vars['title'];
518
519 $template->assign_vars(array(
520 'L_TITLE' => $user->lang[$display_vars['title']],
521 'L_TITLE_EXPLAIN' => $user->lang[$display_vars['title'] . '_EXPLAIN'],
522
523 'S_ERROR' => (sizeof($error)) ? true : false,
524 'ERROR_MSG' => implode('<br />', $error),
525
526 'U_ACTION' => $this->u_action)
527 );
528
529 // Output relevant page
530 foreach ($display_vars['vars'] as $config_key => $vars)
531 {
532 if (!is_array($vars) && strpos($config_key, 'legend') === false)
533 {
534 continue;
535 }
536
537 if (strpos($config_key, 'legend') !== false)
538 {
539 $template->assign_block_vars('options', array(
540 'S_LEGEND' => true,
541 'LEGEND' => (isset($user->lang[$vars])) ? $user->lang[$vars] : $vars)
542 );
543
544 continue;
545 }
546
547 $type = explode(':', $vars['type']);
548
549 $l_explain = '';
550 if ($vars['explain'] && isset($vars['lang_explain']))
551 {
552 $l_explain = (isset($user->lang[$vars['lang_explain']])) ? $user->lang[$vars['lang_explain']] : $vars['lang_explain'];
553 }
554 else if ($vars['explain'])
555 {
556 $l_explain = (isset($user->lang[$vars['lang'] . '_EXPLAIN'])) ? $user->lang[$vars['lang'] . '_EXPLAIN'] : '';
557 }
558
559 $template->assign_block_vars('options', array(
560 'KEY' => $config_key,
561 'TITLE' => (isset($user->lang[$vars['lang']])) ? $user->lang[$vars['lang']] : $vars['lang'],
562 'S_EXPLAIN' => $vars['explain'],
563 'TITLE_EXPLAIN' => $l_explain,
564 'CONTENT' => build_cfg_template($type, $config_key, $this->new_config, $config_key, $vars),
565 )
566 );
567
568 unset($display_vars['vars'][$config_key]);
569 }
570
571 if ($mode == 'auth')
572 {
573 $template->assign_var('S_AUTH', true);
574
575 foreach ($auth_plugins as $method)
576 {
577 if ($method && file_exists($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx))
578 {
579 $method = 'acp_' . $method;
580 if (function_exists($method))
581 {
582 $fields = $method($this->new_config);
583
584 if ($fields['tpl'])
585 {
586 $template->assign_block_vars('auth_tpl', array(
587 'TPL' => $fields['tpl'])
588 );
589 }
590 unset($fields);
591 }
592 }
593 }
594 }
595 }
596
597 /**
598 * Select auth method
599 */
600 function select_auth_method($selected_method, $key = '')
601 {
602 global $phpbb_root_path, $phpEx;
603
604 $auth_plugins = array();
605
606 $dp = @opendir($phpbb_root_path . 'includes/auth');
607
608 if (!$dp)
609 {
610 return '';
611 }
612
613 while (($file = readdir($dp)) !== false)
614 {
615 if (preg_match('#^auth_(.*?)\.' . $phpEx . '$#', $file))
616 {
617 $auth_plugins[] = preg_replace('#^auth_(.*?)\.' . $phpEx . '$#', '\1', $file);
618 }
619 }
620 closedir($dp);
621
622 sort($auth_plugins);
623
624 $auth_select = '';
625 foreach ($auth_plugins as $method)
626 {
627 $selected = ($selected_method == $method) ? ' selected="selected"' : '';
628 $auth_select .= '<option value="' . $method . '"' . $selected . '>' . ucfirst($method) . '</option>';
629 }
630
631 return $auth_select;
632 }
633
634 /**
635 * Select mail authentication method
636 */
637 function mail_auth_select($selected_method, $key = '')
638 {
639 global $user;
640
641 $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP');
642 $s_smtp_auth_options = '';
643
644 foreach ($auth_methods as $method)
645 {
646 $s_smtp_auth_options .= '<option value="' . $method . '"' . (($selected_method == $method) ? ' selected="selected"' : '') . '>' . $user->lang['SMTP_' . str_replace('-', '_', $method)] . '</option>';
647 }
648
649 return $s_smtp_auth_options;
650 }
651
652 /**
653 * Select full folder action
654 */
655 function full_folder_select($value, $key = '')
656 {
657 global $user;
658
659 return '<option value="1"' . (($value == 1) ? ' selected="selected"' : '') . '>' . $user->lang['DELETE_OLDEST_MESSAGES'] . '</option><option value="2"' . (($value == 2) ? ' selected="selected"' : '') . '>' . $user->lang['HOLD_NEW_MESSAGES_SHORT'] . '</option>';
660 }
661
662 /**
663 * Select ip validation
664 */
665 function select_ip_check($value, $key = '')
666 {
667 $radio_ary = array(4 => 'ALL', 3 => 'CLASS_C', 2 => 'CLASS_B', 0 => 'NO_IP_VALIDATION');
668
669 return h_radio('config[ip_check]', $radio_ary, $value, $key);
670 }
671
672 /**
673 * Select account activation method
674 */
675 function select_acc_activation($value, $key = '')
676 {
677 global $user, $config;
678
679 $radio_ary = array(USER_ACTIVATION_DISABLE => 'ACC_DISABLE', USER_ACTIVATION_NONE => 'ACC_NONE');
680 if ($config['email_enable'])
681 {
682 $radio_ary += array(USER_ACTIVATION_SELF => 'ACC_USER', USER_ACTIVATION_ADMIN => 'ACC_ADMIN');
683 }
684
685 return h_radio('config[require_activation]', $radio_ary, $value, $key);
686 }
687
688 /**
689 * Maximum/Minimum username length
690 */
691 function username_length($value, $key = '')
692 {
693 global $user;
694
695 return '<input id="' . $key . '" type="text" size="3" maxlength="3" name="config[min_name_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . ' <input type="text" size="3" maxlength="3" name="config[max_name_chars]" value="' . $this->new_config['max_name_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
696 }
697
698 /**
699 * Allowed chars in usernames
700 */
701 function select_username_chars($selected_value, $key)
702 {
703 global $user;
704
705 $user_char_ary = array('USERNAME_CHARS_ANY', 'USERNAME_ALPHA_ONLY', 'USERNAME_ALPHA_SPACERS', 'USERNAME_LETTER_NUM', 'USERNAME_LETTER_NUM_SPACERS', 'USERNAME_ASCII');
706 $user_char_options = '';
707 foreach ($user_char_ary as $user_type)
708 {
709 $selected = ($selected_value == $user_type) ? ' selected="selected"' : '';
710 $user_char_options .= '<option value="' . $user_type . '"' . $selected . '>' . $user->lang[$user_type] . '</option>';
711 }
712
713 return $user_char_options;
714 }
715
716 /**
717 * Maximum/Minimum password length
718 */
719 function password_length($value, $key)
720 {
721 global $user;
722
723 return '<input id="' . $key . '" type="text" size="3" maxlength="3" name="config[min_pass_chars]" value="' . $value . '" /> ' . $user->lang['MIN_CHARS'] . ' <input type="text" size="3" maxlength="3" name="config[max_pass_chars]" value="' . $this->new_config['max_pass_chars'] . '" /> ' . $user->lang['MAX_CHARS'];
724 }
725
726 /**
727 * Required chars in passwords
728 */
729 function select_password_chars($selected_value, $key)
730 {
731 global $user;
732
733 $pass_type_ary = array('PASS_TYPE_ANY', 'PASS_TYPE_CASE', 'PASS_TYPE_ALPHA', 'PASS_TYPE_SYMBOL');
734 $pass_char_options = '';
735 foreach ($pass_type_ary as $pass_type)
736 {
737 $selected = ($selected_value == $pass_type) ? ' selected="selected"' : '';
738 $pass_char_options .= '<option value="' . $pass_type . '"' . $selected . '>' . $user->lang[$pass_type] . '</option>';
739 }
740
741 return $pass_char_options;
742 }
743
744 /**
745 * Select bump interval
746 */
747 function bump_interval($value, $key)
748 {
749 global $user;
750
751 $s_bump_type = '';
752 $types = array('m' => 'MINUTES', 'h' => 'HOURS', 'd' => 'DAYS');
753 foreach ($types as $type => $lang)
754 {
755 $selected = ($this->new_config['bump_type'] == $type) ? ' selected="selected"' : '';
756 $s_bump_type .= '<option value="' . $type . '"' . $selected . '>' . $user->lang[$lang] . '</option>';
757 }
758
759 return '<input id="' . $key . '" type="text" size="3" maxlength="4" name="config[bump_interval]" value="' . $value . '" /> <select name="config[bump_type]">' . $s_bump_type . '</select>';
760 }
761
762 /**
763 * Board disable option and message
764 */
765 function board_disable($value, $key)
766 {
767 global $user;
768
769 $radio_ary = array(1 => 'YES', 0 => 'NO');
770
771 return h_radio('config[board_disable]', $radio_ary, $value) . '<br /><input id="' . $key . '" type="text" name="config[board_disable_msg]" maxlength="255" size="40" value="' . $this->new_config['board_disable_msg'] . '" />';
772 }
773
774 /**
775 * Select default dateformat
776 */
777 function dateformat_select($value, $key)
778 {
779 global $user, $config;
780
781 // Let the format_date function operate with the acp values
782 $old_tz = $user->timezone;
783 $old_dst = $user->dst;
784
785 $user->timezone = $config['board_timezone'];
786 $user->dst = $config['board_dst'];
787
788 $dateformat_options = '';
789
790 foreach ($user->lang['dateformats'] as $format => $null)
791 {
792 $dateformat_options .= '<option value="' . $format . '"' . (($format == $value) ? ' selected="selected"' : '') . '>';
793 $dateformat_options .= $user->format_date(time(), $format, false) . ((strpos($format, '|') !== false) ? $user->lang['VARIANT_DATE_SEPARATOR'] . $user->format_date(time(), $format, true) : '');
794 $dateformat_options .= '</option>';
795 }
796
797 $dateformat_options .= '<option value="custom"';
798 if (!in_array($value, array_keys($user->lang['dateformats'])))
799 {
800 $dateformat_options .= ' selected="selected"';
801 }
802 $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . '</option>';
803
804 // Reset users date options
805 $user->timezone = $old_tz;
806 $user->dst = $old_dst;
807
808 return "<select name=\"dateoptions\" id=\"dateoptions\" onchange=\"if (this.value == 'custom') { document.getElementById('" . addslashes($key) . "').value = '" . addslashes($value) . "'; } else { document.getElementById('" . addslashes($key) . "').value = this.value; }\">$dateformat_options</select>
809 <input type=\"text\" name=\"config[$key]\" id=\"$key\" value=\"$value\" maxlength=\"30\" />";
810 }
811 }
812
813 ?>