add some properties
[phpbb.git] / phpBB / install / install_install.php
blobc8d9df2b285109358e9676448c705285e2f1f1b0
1 <?php
2 /**
4 * @package install
5 * @version $Id$
6 * @copyright (c) 2005 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9 */
11 /**
13 if (!defined('IN_INSTALL'))
15 // Someone has tried to access the file direct. This is not a good idea, so exit
16 exit;
19 if (!empty($setmodules))
21 // If phpBB is already installed we do not include this module
22 if (@file_exists(PHPBB_ROOT_PATH . 'config.' . PHP_EXT) && !file_exists(PHPBB_ROOT_PATH . 'cache/install_lock'))
24 include PHPBB_ROOT_PATH . 'config.' . PHP_EXT;
26 if (phpbb::$base_config['installed'])
28 return;
32 $module[] = array(
33 'module_type' => 'install',
34 'module_title' => 'INSTALL',
35 'module_filename' => substr(basename(__FILE__), 0, -strlen(PHP_EXT)-1),
36 'module_order' => 10,
37 'module_subs' => '',
38 'module_stages' => array('INTRO', 'REQUIREMENTS', 'DATABASE', 'ADMINISTRATOR', 'CONFIG_FILE', 'ADVANCED', 'CREATE_TABLE', 'FINAL'),
39 'module_reqs' => ''
43 /**
44 * Installation
45 * @package install
47 class install_install extends module
49 function install_install(&$p_master)
51 $this->p_master = &$p_master;
54 function main($mode, $sub)
56 phpbb::$template->assign_vars(array(
57 'S_SUB' => $sub,
58 'S_LANG_SELECT' => '<select id="language" name="language">' . $this->p_master->inst_language_select(phpbb::$user->lang_name) . '</select>',
59 ));
61 switch ($sub)
63 case 'intro':
64 $this->page_title = 'SUB_INTRO';
66 phpbb::$template->assign_vars(array(
67 'U_ACTION' => phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=requirements&amp;language=" . phpbb::$user->lang_name),
68 ));
70 break;
72 case 'requirements':
73 $this->page_title = 'STAGE_REQUIREMENTS';
74 $this->check_server_requirements($mode, $sub);
75 break;
77 case 'database':
78 $this->page_title = 'STAGE_DATABASE';
80 // Obtain any submitted data
81 $data = $this->get_submitted_data();
83 $this->obtain_database_settings($mode, $sub, $data);
84 break;
86 case 'administrator':
87 $this->page_title = 'STAGE_ADMINISTRATOR';
89 phpbb::$user->add_lang('acp/board');
91 // Obtain any submitted data
92 $data = $this->get_submitted_data();
94 $this->obtain_admin_settings($mode, $sub, $data);
96 break;
98 case 'config_file':
99 $this->page_title = 'STAGE_CONFIG_FILE';
101 // Obtain any submitted data
102 $data = $this->get_submitted_data();
104 $this->create_config_file($mode, $sub, $data);
105 break;
107 case 'advanced':
108 $this->page_title = 'STAGE_ADVANCED';
110 phpbb::$user->add_lang('acp/common');
111 phpbb::$user->add_lang('acp/board');
113 // Obtain any submitted data
114 $data = $this->get_submitted_data();
116 $this->obtain_advanced_settings($mode, $sub, $data);
117 break;
119 case 'create_table':
120 $this->page_title = 'STAGE_CREATE_TABLE';
122 // Obtain any submitted data
123 $data = $this->get_submitted_data();
125 $this->load_schema($mode, $sub, $data);
126 break;
128 case 'final':
129 $this->page_title = 'STAGE_FINAL';
131 include PHPBB_ROOT_PATH . 'common.' . PHP_EXT;
133 phpbb::$acm->purge();
135 $this->build_search_index($mode, $sub);
136 $this->add_modules($mode, $sub);
137 $this->add_language($mode, $sub);
138 $this->add_bots($mode, $sub);
139 $this->email_admin($mode, $sub);
141 // Remove the lock file
142 @unlink(PHPBB_ROOT_PATH . 'cache/install_lock');
144 break;
147 $this->tpl_name = 'install/install';
150 function build_form($data, $form_array)
152 foreach ($form_array as $config_key => $vars)
154 if (!is_array($vars) && strpos($config_key, 'legend') === false)
156 continue;
159 if (strpos($config_key, 'legend') !== false)
161 phpbb::$template->assign_block_vars('options', array(
162 'S_LEGEND' => true,
163 'LEGEND' => phpbb::$user->lang[$vars],
166 continue;
169 $options = isset($vars['options']) ? $vars['options'] : '';
171 phpbb::$template->assign_block_vars('options', array(
172 'KEY' => $config_key,
173 'TITLE' => phpbb::$user->lang[$vars['lang']],
174 'S_EXPLAIN' => $vars['explain'],
175 'TITLE_EXPLAIN' => ($vars['explain']) ? phpbb::$user->lang[$vars['lang'] . '_EXPLAIN'] : '',
176 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
181 function return_hidden_fields()
183 $args = func_get_args();
184 $data = array_shift($args);
186 $s_hidden_fields = '';
188 foreach ($args as $argument)
190 if (!is_array($argument))
192 continue;
195 foreach ($argument as $config_key => $vars)
197 if (!is_array($vars))
199 continue;
202 $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
206 return $s_hidden_fields;
210 * Checks that the server we are installing on meets the requirements for running phpBB
212 function check_server_requirements($mode, $sub)
214 $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false,);
216 // Test for basic PHP settings
217 phpbb::$template->assign_block_vars('checks', array(
218 'S_LEGEND' => true,
219 'LEGEND' => phpbb::$user->lang['PHP_SETTINGS'],
220 'LEGEND_EXPLAIN' => phpbb::$user->lang['PHP_SETTINGS_EXPLAIN'],
223 // Test the minimum PHP version
224 if (version_compare(PHP_VERSION, '5.2.0') < 0)
226 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
228 else
230 $passed['php'] = true;
232 // We also give feedback on whether we're running in safe mode
233 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'];
234 if (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) == 'on')
236 $result .= ', ' . phpbb::$user->lang['PHP_SAFE_MODE'];
238 $result .= '</strong>';
241 phpbb::$template->assign_block_vars('checks', array(
242 'TITLE' => phpbb::$user->lang['PHP_VERSION_REQD'],
243 'RESULT' => $result,
246 // Check for register_globals being enabled
247 if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on')
249 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
251 else
253 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
256 phpbb::$template->assign_block_vars('checks', array(
257 'TITLE' => phpbb::$user->lang['PHP_REGISTER_GLOBALS'],
258 'TITLE_EXPLAIN' => phpbb::$user->lang['PHP_REGISTER_GLOBALS_EXPLAIN'],
259 'RESULT' => $result,
261 'S_EXPLAIN' => true,
264 // Check for url_fopen
265 if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on')
267 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
269 else
271 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
274 phpbb::$template->assign_block_vars('checks', array(
275 'TITLE' => phpbb::$user->lang['PHP_URL_FOPEN_SUPPORT'],
276 'TITLE_EXPLAIN' => phpbb::$user->lang['PHP_URL_FOPEN_SUPPORT_EXPLAIN'],
277 'RESULT' => $result,
279 'S_EXPLAIN' => true,
282 // Check for getimagesize
283 if (@function_exists('getimagesize'))
285 $passed['imagesize'] = true;
286 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
288 else
290 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
293 phpbb::$template->assign_block_vars('checks', array(
294 'TITLE' => phpbb::$user->lang['PHP_GETIMAGESIZE_SUPPORT'],
295 'TITLE_EXPLAIN' => phpbb::$user->lang['PHP_GETIMAGESIZE_SUPPORT_EXPLAIN'],
296 'RESULT' => $result,
298 'S_EXPLAIN' => true,
301 // Check for PCRE UTF-8 support
302 if (@preg_match('//u', ''))
304 $passed['pcre'] = true;
305 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
307 else
309 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
312 phpbb::$template->assign_block_vars('checks', array(
313 'TITLE' => phpbb::$user->lang['PCRE_UTF_SUPPORT'],
314 'TITLE_EXPLAIN' => phpbb::$user->lang['PCRE_UTF_SUPPORT_EXPLAIN'],
315 'RESULT' => $result,
317 'S_EXPLAIN' => true,
320 // Check for PCRE unicode property support
321 if (@preg_match('/\p{Ll}/u', 'a'))
323 $passed['pcre'] = true;
324 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
326 else
328 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
331 phpbb::$template->assign_block_vars('checks', array(
332 'TITLE' => phpbb::$user->lang['PCRE_UNI_PROP_SUPPORT'],
333 'TITLE_EXPLAIN' => phpbb::$user->lang['PCRE_UNI_PROP_SUPPORT_EXPLAIN'],
334 'RESULT' => $result,
336 'S_EXPLAIN' => true,
339 // MBString passes always. If the extension is loaded it only can interfere with our functions, set to false then
340 $passed['mbstring'] = true;
341 if (@extension_loaded('mbstring'))
343 // Test for available database modules
344 phpbb::$template->assign_block_vars('checks', array(
345 'S_LEGEND' => true,
346 'LEGEND' => phpbb::$user->lang['MBSTRING_CHECK'],
347 'LEGEND_EXPLAIN' => phpbb::$user->lang['MBSTRING_CHECK_EXPLAIN'],
350 $checks = array(
351 array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING),
352 array('encoding_translation', '!=', 0),
353 array('http_input', '!=', 'pass'),
354 array('http_output', '!=', 'pass')
357 foreach ($checks as $mb_checks)
359 $ini_val = @ini_get('mbstring.' . $mb_checks[0]);
360 switch ($mb_checks[1])
362 case '&':
363 if (intval($ini_val) & $mb_checks[2])
365 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
366 $passed['mbstring'] = false;
368 else
370 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
372 break;
374 case '!=':
375 if ($ini_val != $mb_checks[2])
377 $result = '<strong style="color:red">' . phpbb::$user->lang['NO'] . '</strong>';
378 $passed['mbstring'] = false;
380 else
382 $result = '<strong style="color:green">' . phpbb::$user->lang['YES'] . '</strong>';
384 break;
387 phpbb::$template->assign_block_vars('checks', array(
388 'TITLE' => phpbb::$user->lang['MBSTRING_' . strtoupper($mb_checks[0])],
389 'TITLE_EXPLAIN' => phpbb::$user->lang['MBSTRING_' . strtoupper($mb_checks[0]) . '_EXPLAIN'],
390 'RESULT' => $result,
392 'S_EXPLAIN' => true,
397 // Test for available database modules
398 phpbb::$template->assign_block_vars('checks', array(
399 'S_LEGEND' => true,
400 'LEGEND' => phpbb::$user->lang['PHP_SUPPORTED_DB'],
401 'LEGEND_EXPLAIN' => phpbb::$user->lang['PHP_SUPPORTED_DB_EXPLAIN'],
404 $available_dbms = get_available_dbms(false, true);
405 $passed['db'] = $available_dbms['ANY_DB_SUPPORT'];
406 unset($available_dbms['ANY_DB_SUPPORT']);
408 foreach ($available_dbms as $db_name => $db_ary)
410 if (!$db_ary['AVAILABLE'])
412 phpbb::$template->assign_block_vars('checks', array(
413 'TITLE' => phpbb::$user->lang['DLL_' . strtoupper($db_name)],
414 'RESULT' => '<span style="color:red">' . phpbb::$user->lang['UNAVAILABLE'] . '</span>',
417 else
419 phpbb::$template->assign_block_vars('checks', array(
420 'TITLE' => phpbb::$user->lang['DLL_' . strtoupper($db_name)],
421 'RESULT' => '<strong style="color:green">' . phpbb::$user->lang['AVAILABLE'] . '</strong>',
426 // Test for other modules
427 phpbb::$template->assign_block_vars('checks', array(
428 'S_LEGEND' => true,
429 'LEGEND' => phpbb::$user->lang['PHP_OPTIONAL_MODULE'],
430 'LEGEND_EXPLAIN' => phpbb::$user->lang['PHP_OPTIONAL_MODULE_EXPLAIN'],
433 foreach ($this->php_dlls_other as $dll)
435 if (!@extension_loaded($dll))
437 if (!can_load_dll($dll))
439 phpbb::$template->assign_block_vars('checks', array(
440 'TITLE' => phpbb::$user->lang['DLL_' . strtoupper($dll)],
441 'RESULT' => '<strong style="color:red">' . phpbb::$user->lang['UNAVAILABLE'] . '</strong>',
443 continue;
447 phpbb::$template->assign_block_vars('checks', array(
448 'TITLE' => phpbb::$user->lang['DLL_' . strtoupper($dll)],
449 'RESULT' => '<strong style="color:green">' . phpbb::$user->lang['AVAILABLE'] . '</strong>',
453 // Can we find Imagemagick anywhere on the system?
454 $exe = (DIRECTORY_SEPARATOR == '\\') ? '.exe' : '';
456 $magic_home = getenv('MAGICK_HOME');
457 $img_imagick = '';
458 if (empty($magic_home))
460 $locations = array('C:/WINDOWS/', 'C:/WINNT/', 'C:/WINDOWS/SYSTEM/', 'C:/WINNT/SYSTEM/', 'C:/WINDOWS/SYSTEM32/', 'C:/WINNT/SYSTEM32/', '/usr/bin/', '/usr/sbin/', '/usr/local/bin/', '/usr/local/sbin/', '/opt/', '/usr/imagemagick/', '/usr/bin/imagemagick/');
461 $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH'))));
463 $locations = array_merge($path_locations, $locations);
464 foreach ($locations as $location)
466 // The path might not end properly, fudge it
467 if (substr($location, -1, 1) !== '/')
469 $location .= '/';
472 if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000)
474 $img_imagick = str_replace('\\', '/', $location);
475 continue;
479 else
481 $img_imagick = str_replace('\\', '/', $magic_home);
484 phpbb::$template->assign_block_vars('checks', array(
485 'TITLE' => phpbb::$user->lang['APP_MAGICK'],
486 'RESULT' => ($img_imagick) ? '<strong style="color:green">' . phpbb::$user->lang['AVAILABLE'] . ', ' . htmlspecialchars($img_imagick) . '</strong>' : '<strong style="color:blue">' . phpbb::$user->lang['NO_LOCATION'] . '</strong>',
489 // Check permissions on files/directories we need access to
490 phpbb::$template->assign_block_vars('checks', array(
491 'S_LEGEND' => true,
492 'LEGEND' => phpbb::$user->lang['FILES_REQUIRED'],
493 'LEGEND_EXPLAIN' => phpbb::$user->lang['FILES_REQUIRED_EXPLAIN'],
496 $directories = array('cache/', 'files/', 'store/');
498 umask(0);
500 $passed['files'] = true;
501 foreach ($directories as $dir)
503 $exists = $write = false;
505 // Try to create the directory if it does not exist
506 if (!file_exists(PHPBB_ROOT_PATH . $dir))
508 @mkdir(PHPBB_ROOT_PATH . $dir, 0777);
509 phpbb::$system->chmod(PHPBB_ROOT_PATH . $dir, phpbb::CHMOD_READ | phpbb::CHMOD_WRITE);
512 // Now really check
513 if (file_exists(PHPBB_ROOT_PATH . $dir) && is_dir(PHPBB_ROOT_PATH . $dir))
515 phpbb::$system->chmod(PHPBB_ROOT_PATH . $dir, phpbb::CHMOD_READ | phpbb::CHMOD_WRITE);
516 $exists = true;
519 // Now check if it is writable by storing a simple file
520 $fp = @fopen(PHPBB_ROOT_PATH . $dir . 'test_lock', 'wb');
521 if ($fp !== false)
523 $write = true;
525 @fclose($fp);
527 @unlink(PHPBB_ROOT_PATH . $dir . 'test_lock');
529 $passed['files'] = ($exists && $write && $passed['files']) ? true : false;
531 $exists = ($exists) ? '<strong style="color:green">' . phpbb::$user->lang['FOUND'] . '</strong>' : '<strong style="color:red">' . phpbb::$user->lang['NOT_FOUND'] . '</strong>';
532 $write = ($write) ? ', <strong style="color:green">' . phpbb::$user->lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . phpbb::$user->lang['UNWRITABLE'] . '</strong>' : '');
534 phpbb::$template->assign_block_vars('checks', array(
535 'TITLE' => $dir,
536 'RESULT' => $exists . $write,
540 // Check permissions on files/directories it would be useful access to
541 phpbb::$template->assign_block_vars('checks', array(
542 'S_LEGEND' => true,
543 'LEGEND' => phpbb::$user->lang['FILES_OPTIONAL'],
544 'LEGEND_EXPLAIN' => phpbb::$user->lang['FILES_OPTIONAL_EXPLAIN'],
547 $directories = array('config.' . PHP_EXT, 'images/avatars/upload/');
549 foreach ($directories as $dir)
551 $write = $exists = true;
552 if (file_exists(PHPBB_ROOT_PATH . $dir))
554 if (!@is_writable(PHPBB_ROOT_PATH . $dir))
556 $write = false;
559 else
561 $write = $exists = false;
564 $exists_str = ($exists) ? '<strong style="color:green">' . phpbb::$user->lang['FOUND'] . '</strong>' : '<strong style="color:red">' . phpbb::$user->lang['NOT_FOUND'] . '</strong>';
565 $write_str = ($write) ? ', <strong style="color:green">' . phpbb::$user->lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . phpbb::$user->lang['UNWRITABLE'] . '</strong>' : '');
567 phpbb::$template->assign_block_vars('checks', array(
568 'TITLE' => $dir,
569 'RESULT' => $exists_str . $write_str,
573 // And finally where do we want to go next (well today is taken isn't it :P)
574 $s_hidden_fields = ($img_imagick) ? '<input type="hidden" name="img_imagick" value="' . htmlspecialchars($img_imagick) . '" />' : '';
576 $url = (!in_array(false, $passed)) ? phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=database&amp;language=" . phpbb::$user->lang_name) : phpbb::$url->build_url();
578 phpbb::$template->assign_vars(array(
579 'S_FAILED' => in_array(false, $passed),
580 'S_HIDDEN' => $s_hidden_fields,
581 'U_ACTION_TEST' => phpbb::$url->build_url(),
582 'U_ACTION' => $url,
587 * Obtain the information required to connect to the database
589 function obtain_database_settings($mode, $sub, &$data)
591 $connect_test = false;
592 $error = array();
594 $available_dbms = get_available_dbms();
596 // Has the user opted to test the connection?
597 if (phpbb_request::is_set_post('testdb'))
599 if (!isset($available_dbms[$data['dbms']]))
601 $error[] = phpbb::$user->lang['INST_ERR_NO_DB'];
602 $connect_test = false;
604 else
606 $connect_test = connect_check_db($available_dbms[$data['dbms']], $data['table_prefix'], $data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], $error);
609 if ($connect_test)
611 phpbb::$template->assign_vars(array(
612 'S_CONNECT_TEST' => true,
613 'S_SUCCESS' => true,
616 else
618 phpbb::$template->assign_vars(array(
619 'S_CONNECT_TEST' => true,
620 'ERROR' => implode('<br />', $error),
625 if (!$connect_test)
627 // And now for the main part of this page
628 $data['table_prefix'] = (!empty($data['table_prefix']) ? $data['table_prefix'] : 'phpbb_');
629 $this->build_form($data, $this->db_config_options);
632 // And finally where do we want to go next (well today is taken isn't it :P)
633 $s_hidden_fields = $this->return_hidden_fields($data, $this->common_config_options);
635 if ($connect_test)
637 $s_hidden_fields .= $this->return_hidden_fields($data, $this->db_config_options);
640 $url = ($connect_test) ? phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=administrator") : phpbb::$url->build_url();
641 $s_hidden_fields .= ($connect_test) ? '' : '<input type="hidden" name="testdb" value="true" />';
643 phpbb::$template->assign_vars(array(
644 'S_HIDDEN' => $s_hidden_fields,
645 'U_ACTION' => $url,
650 * Obtain the administrator's name, password and email address
652 function obtain_admin_settings($mode, $sub, &$data)
654 if ($data['dbms'] == '')
656 // Someone's been silly and tried calling this page direct
657 // So we send them back to the start to do it again properly
658 $this->p_master->redirect('index.' . PHP_EXT . '?mode=install');
661 $passed = false;
662 $data['default_lang'] = ($data['default_lang'] !== '') ? $data['default_lang'] : $data['language'];
664 if (phpbb_request::is_set_post('check'))
666 $error = array();
668 // Check the entered email address and password
669 if ($data['admin_name'] == '' || $data['admin_pass1'] == '' || $data['admin_pass2'] == '' || $data['board_email'] == '' || $data['board_contact'] == '')
671 $error[] = phpbb::$user->lang['INST_ERR_MISSING_DATA'];
674 if ($data['admin_pass1'] != $data['admin_pass2'] && $data['admin_pass1'] != '')
676 $error[] = phpbb::$user->lang['INST_ERR_PASSWORD_MISMATCH'];
679 // Test against the default username rules
680 if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) < 3)
682 $error[] = phpbb::$user->lang['INST_ERR_USER_TOO_SHORT'];
685 if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) > 20)
687 $error[] = phpbb::$user->lang['INST_ERR_USER_TOO_LONG'];
690 // Test against the default password rules
691 if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) < 6)
693 $error[] = phpbb::$user->lang['INST_ERR_PASSWORD_TOO_SHORT'];
696 if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) > 30)
698 $error[] = phpbb::$user->lang['INST_ERR_PASSWORD_TOO_LONG'];
701 if ($data['board_email'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_email']))
703 $error[] = phpbb::$user->lang['INST_ERR_EMAIL_INVALID'];
706 if ($data['board_contact'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_contact']))
708 $error[] = phpbb::$user->lang['INST_ERR_EMAIL_INVALID'];
711 phpbb::$template->assign_block_vars('checks', array(
712 'S_LEGEND' => true,
713 'LEGEND' => phpbb::$user->lang['STAGE_ADMINISTRATOR'],
716 if (!sizeof($error))
718 $passed = true;
720 phpbb::$template->assign_block_vars('checks', array(
721 'TITLE' => phpbb::$user->lang['ADMIN_TEST'],
722 'RESULT' => '<strong style="color:green">' . phpbb::$user->lang['TESTS_PASSED'] . '</strong>',
725 else
727 phpbb::$template->assign_block_vars('checks', array(
728 'TITLE' => phpbb::$user->lang['ADMIN_TEST'],
729 'RESULT' => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
734 $s_hidden_fields = '';
736 if (!$passed)
738 $this->build_form($data, $this->admin_config_options);
740 else
742 $s_hidden_fields .= $this->return_hidden_fields($data, $this->admin_config_options);
745 $s_hidden_fields .= $this->return_hidden_fields($data, $this->common_config_options, $this->db_config_options);
747 $url = ($passed) ? phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=config_file") : phpbb::$url->build_url();
748 $s_hidden_fields .= ($passed) ? '' : '<input type="hidden" name="check" value="true" />';
750 phpbb::$template->assign_vars(array(
751 'S_HIDDEN' => $s_hidden_fields,
752 'U_ACTION' => $url,
757 * Writes the config file to disk, or if unable to do so offers alternative methods
759 function create_config_file($mode, $sub, &$data)
761 if ($data['dbms'] == '')
763 // Someone's been silly and tried calling this page direct
764 // So we send them back to the start to do it again properly
765 $this->p_master->redirect('index.' . PHP_EXT . '?mode=install');
768 $s_hidden_fields = $this->return_hidden_fields($data, $this->common_config_options);
769 $written = false;
771 // Create a list of any PHP modules we wish to have loaded
772 $load_extensions = array();
773 $available_dbms = get_available_dbms($data['dbms']);
775 $check_exts = array_merge($this->php_dlls_other);
777 foreach ($check_exts as $dll)
779 if (!@extension_loaded($dll))
781 if (!can_load_dll($dll))
783 continue;
786 $load_extensions[] = $dll . '.' . PHP_SHLIB_SUFFIX;
790 $db_module = $available_dbms[$data['dbms']]['MODULE'];
792 if (!is_array($db_module))
794 $db_module = array($db_module);
797 $load_dll = true;
798 foreach ($db_module as $dll)
800 if (@extension_loaded($dll))
802 $load_dll = false;
803 break;
806 if (!can_load_dll($dll))
808 $load_dll = false;
809 break;
812 $load_dll = true;
815 if ($load_dll)
817 $dll = current($db_module);
818 $load_extensions[] = $dll . '.' . PHP_SHLIB_SUFFIX;
821 // Create a lock file to indicate that there is an install in progress
822 $fp = @fopen(PHPBB_ROOT_PATH . 'cache/install_lock', 'wb');
823 if ($fp === false)
825 // We were unable to create the lock file - abort
826 trigger_error(phpbb::$user->lang['UNABLE_WRITE_LOCK'], E_USER_ERROR);
828 @fclose($fp);
830 phpbb::$system->chmod(PHPBB_ROOT_PATH . 'cache/install_lock', phpbb::CHMOD_READ | phpbb::CHMOD_WRITE);
832 $load_extensions = implode(',', $load_extensions);
834 // Time to convert the data provided into a config file
835 $config_data = "<?php\n";
836 $config_data .= "// phpBB 3.0.x auto-generated configuration file\n// Do not change anything in this file!\n";
837 $config_data .= "if (class_exists('phpbb') && defined('IN_PHPBB'))\n{\n\tphpbb::set_config(array(\n";
839 $config_data_array = array(
840 'dbms' => $available_dbms[$data['dbms']]['DRIVER'],
841 'dbhost' => $data['dbhost'],
842 'dbport' => $data['dbport'],
843 'dbname' => $data['dbname'],
844 'dbuser' => $data['dbuser'],
845 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']),
846 'table_prefix' => $data['table_prefix'],
847 'admin_folder' => 'adm',
848 'acm_type' => 'file',
849 'extensions' => $load_extensions,
852 foreach ($config_data_array as $key => $value)
854 $config_data .= "\t\t'{$key}' => '" . str_replace("'", "\\'", str_replace('\\', '\\\\', $value)) . "',\n";
856 unset($config_data_array);
858 $config_data .= "\n\t\t'debug' => true,\n\t\t'debug_extra' => true,\n\n\t\t// DO NOT CHANGE\n\t\t'installed' => true,\n\t));\n}\n";
859 $config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused!
861 // Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
862 if ((file_exists(PHPBB_ROOT_PATH . 'config.' . PHP_EXT) && is_writable(PHPBB_ROOT_PATH . 'config.' . PHP_EXT)) || is_writable(PHPBB_ROOT_PATH))
864 // Assume it will work ... if nothing goes wrong below
865 $written = true;
867 if (!($fp = @fopen(PHPBB_ROOT_PATH . 'config.' . PHP_EXT, 'w')))
869 // Something went wrong ... so let's try another method
870 $written = false;
873 if (!(@fwrite($fp, $config_data)))
875 // Something went wrong ... so let's try another method
876 $written = false;
879 @fclose($fp);
881 if ($written)
883 @chmod(PHPBB_ROOT_PATH . 'config.' . PHP_EXT, 0644);
887 if (phpbb_request::is_set_post('dldone'))
889 // Do a basic check to make sure that the file has been uploaded
890 // Note that all we check is that the file has _something_ in it
891 // We don't compare the contents exactly - if they can't upload
892 // a single file correctly, it's likely they will have other problems....
893 if (filesize(PHPBB_ROOT_PATH . 'config.' . PHP_EXT) > 10)
895 $written = true;
899 $s_hidden_fields .= $this->return_hidden_fields($data, $this->db_config_options, $this->admin_config_options);
901 if (!$written)
903 // OK, so it didn't work let's try the alternatives
904 if (phpbb_request::is_set_post('dlconfig'))
906 // They want a copy of the file to download, so send the relevant headers and dump out the data
907 header('Content-Type: text/x-delimtext; name="config.' . PHP_EXT . '"');
908 header('Content-disposition: attachment; filename=config.' . PHP_EXT);
909 echo $config_data;
910 exit;
913 // The option to download the config file is always available, so output it here
914 phpbb::$template->assign_vars(array(
915 'S_HIDDEN' => $s_hidden_fields,
916 'U_ACTION' => phpbb::$url->build_url(),
919 else
921 phpbb::$template->assign_vars(array(
922 'S_WRITTEN' => true,
923 'S_HIDDEN' => $s_hidden_fields,
924 'U_ACTION' => phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=advanced"),
930 * Provide an opportunity to customise some advanced settings during the install
931 * in case it is necessary for them to be set to access later
933 function obtain_advanced_settings($mode, $sub, &$data)
935 if ($data['dbms'] == '')
937 // Someone's been silly and tried calling this page direct
938 // So we send them back to the start to do it again properly
939 $this->p_master->redirect('index.' . PHP_EXT . '?mode=install');
942 $s_hidden_fields = $this->return_hidden_fields($data, $this->common_config_options);
944 $data['email_enable'] = ($data['email_enable'] !== '') ? $data['email_enable'] : true;
945 $data['server_name'] = ($data['server_name'] !== '') ? $data['server_name'] : phpbb::$user->system['host'];
946 $data['server_port'] = ($data['server_port'] !== '') ? $data['server_port'] : phpbb::$user->system['port'];
947 $data['server_protocol'] = ($data['server_protocol'] !== '') ? $data['server_protocol'] : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://');
948 $data['cookie_secure'] = ($data['cookie_secure'] !== '') ? $data['cookie_secure'] : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? true : false);
950 if ($data['script_path'] === '')
952 // Replace backslashes and doubled slashes (could happen on some proxy setups)
953 $data['script_path'] = trim(str_replace(array('/install/', '\\install\\'), '', phpbb::$user->page['script_path']));
956 $this->build_form($data, $this->advanced_config_options);
957 $s_hidden_fields .= $this->return_hidden_fields($data, $this->db_config_options, $this->admin_config_options);
959 phpbb::$template->assign_vars(array(
960 'S_HIDDEN' => $s_hidden_fields,
961 'U_ACTION' => phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=create_table"),
966 * Load the contents of the schema into the database and then alter it based on what has been input during the installation
968 function load_schema($mode, $sub, &$data)
970 $s_hidden_fields = '';
972 if ($data['dbms'] == '')
974 // Someone's been silly and tried calling this page direct
975 // So we send them back to the start to do it again properly
976 $this->p_master->redirect('index.' . PHP_EXT . '?mode=install');
979 // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
980 $available_dbms = get_available_dbms($data['dbms']);
982 if (!isset($available_dbms[$data['dbms']]))
984 // Someone's been silly and tried providing a non-existant dbms
985 $this->p_master->redirect('index.' . PHP_EXT . '?mode=install');
988 phpbb::assign('db', phpbb_db_dbal::connect($data['dbms'], $data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false));
990 // Include the db tools - we work with them to create the tables
991 include PHPBB_ROOT_PATH . 'includes/db/db_tools.' . PHP_EXT;
993 // Load the Schema data (Fill $schema_data)
994 include PHPBB_ROOT_PATH . 'install/schemas/schema_structure.' . PHP_EXT;
996 // we do not return statements, we simply let them execute
997 $db_tools = new phpbb_db_tools(phpbb::$db);
999 foreach ($schema_data as $table_name => $table_data)
1001 // Change prefix, we always have phpbb_, therefore we can do a substr() here
1002 $table_name = $data['table_prefix'] . substr($table_name, 6);
1004 // Now create the table
1005 $db_tools->sql_create_table($table_name, $table_data);
1008 // Now get the schema data
1009 include PHPBB_ROOT_PATH . 'install/schemas/schema_data.' . PHP_EXT;
1011 // Build data array for substituted content ;)
1013 $cookie_domain = ($data['server_name'] != '') ? $data['server_name'] : phpbb::$user->system['host'];
1015 // Try to come up with the best solution for cookie domain...
1016 if (strpos($cookie_domain, 'www.') === 0)
1018 $cookie_domain = str_replace('www.', '.', $cookie_domain);
1021 if ($data['script_path'] !== '/')
1023 // Adjust destination path (no trailing slash)
1024 if (substr($data['script_path'], -1) == '/')
1026 $data['script_path'] = substr($data['script_path'], 0, -1);
1029 $data['script_path'] = str_replace(array('../', './'), '', $data['script_path']);
1031 if ($data['script_path'][0] != '/')
1033 $data['script_path'] = '/' . $data['script_path'];
1037 $ref = substr(phpbb::$user->system['referer'], strpos(phpbb::$user->system['referer'], '://') + 3);
1039 $template_data = array(
1040 'BOARD_STARTDATE' => time(),
1041 'CURRENT_TIME' => time(),
1042 'DEFAULT_LANG' => $data['default_lang'],
1043 'DBMS_VERSION' => phpbb::$db->sql_server_info(true),
1044 'IMG_IMAGICK' => $data['img_imagick'],
1045 'SERVER_NAME' => $data['server_name'],
1046 'SERVER_PORT' => $data['server_port'],
1047 'BOARD_EMAIL' => $data['board_email'],
1048 'BOARD_CONTACT' => $data['board_contact'],
1049 'COOKIE_DOMAIN' => $cookie_domain,
1050 'DEFAULT_DATEFORMAT'=> phpbb::$user->lang['default_dateformat'],
1051 'EMAIL_ENABLE' => $data['email_enable'],
1052 'SMTP_DELIVERY' => $data['smtp_delivery'],
1053 'SMTP_HOST' => $data['smtp_host'],
1054 'SMTP_AUTH_METHOD' => $data['smtp_auth'],
1055 'SMTP_USERNAME' => $data['smtp_user'],
1056 'SMTP_PASSWORD' => $data['smtp_pass'],
1057 'COOKIE_SECURE' => $data['cookie_secure'],
1058 'COOKIE_NAME' => 'phpbb3_' . phpbb::$security->gen_rand_string(4),
1059 'FORCE_SERVER_VARS' => $data['force_server_vars'],
1060 'SCRIPT_PATH' => $data['script_path'],
1061 'SERVER_PROTOCOL' => $data['server_protocol'],
1062 'NEWEST_USERNAME' => $data['admin_name'],
1063 'AVATAR_SALT' => md5(phpbb::$security->gen_rand_string()),
1064 'CAPTCHA_PLUGIN' => (@extension_loaded('gd') || can_load_dll('gd')) ? 'phpbb_captcha_gd' : 'phpbb_captcha_nogd',
1065 'REFERER_VALIDATION'=> (!(stripos($ref, phpbb::$user->system['host']) === 0)) ? '0' : '1',
1066 'ADMIN_NAME' => $data['admin_name'],
1067 'ADMIN_NAME_CLEAN' => utf8_clean_string($data['admin_name']),
1068 'ADMIN_PASSWORD' => phpbb::$security->hash_password($data['admin_pass1']),
1069 'ADMIN_EMAIL' => $data['board_contact'],
1070 'ADMIN_EMAIL_HASH' => hexdec(crc32($data['board_contact']) . strlen($data['board_contact'])),
1071 'USER_IP' => phpbb::$user->ip,
1074 // Apply Schema changes
1075 $db_tools->db->sql_transaction('begin');
1077 foreach ($schema_data as $schema_array)
1079 $schema_array['table'] = $data['table_prefix'] . substr($schema_array['table'], 6);
1080 $db_tools->sql_insert_data($schema_array, $template_data);
1083 $db_tools->db->sql_transaction('commit');
1085 // Update data
1086 $db_tools->db->sql_transaction('begin');
1088 foreach ($schema_updates as $schema_array)
1090 $schema_array['table'] = $data['table_prefix'] . substr($schema_array['table'], 6);
1091 $db_tools->sql_update_data($schema_array, $template_data);
1094 $db_tools->db->sql_transaction('commit');
1096 // We need to insert the role data manually... else the schema array is quite large...
1097 $sql = 'SELECT role_id, role_name
1098 FROM ' . $data['table_prefix'] . 'acl_roles';
1099 $result = phpbb::$db->sql_query($sql);
1101 $role_ids = array();
1102 while ($row = phpbb::$db->sql_fetchrow($result))
1104 $role_ids[$row['role_name']] = $row['role_id'];
1106 phpbb::$db->sql_freeresult($result);
1108 foreach ($this->role_definitions as $role_ary)
1110 $role_name = $role_ary[0];
1111 $auth_setting = $role_ary[1];
1112 $permission = $role_ary[2];
1113 $condition = $role_ary[3];
1114 $options = $role_ary[4];
1116 $sql = '';
1117 $sql .= 'INSERT INTO ' . $data['table_prefix'] . 'acl_roles_data (role_id, auth_option_id, auth_setting) ';
1118 $sql .= 'SELECT ' . $role_ids[$role_name] . ', auth_option_id, ' . $auth_setting . ' ';
1119 $sql .= 'FROM ' . $data['table_prefix'] . 'acl_options ';
1120 $sql .= "WHERE auth_option LIKE '{$permission}%'";
1122 if ($options !== false)
1124 $sql .= ' AND auth_option ' . $condition . ' (\'' . implode("', '", $options) . "')";
1127 phpbb::$db->sql_query($sql);
1130 phpbb::$template->assign_vars(array(
1131 'S_HIDDEN' => build_hidden_fields($data),
1132 'U_ACTION' => phpbb::$url->append_sid($this->p_master->module_url, "mode=$mode&amp;sub=final"),
1137 * Build the search index...
1139 function build_search_index($mode, $sub)
1141 include_once PHPBB_ROOT_PATH . 'includes/search/fulltext_native.' . PHP_EXT;
1143 $error = false;
1144 $search = new fulltext_native($error);
1146 $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
1147 FROM ' . POSTS_TABLE;
1148 $result = phpbb::$db->sql_query($sql);
1150 while ($row = phpbb::$db->sql_fetchrow($result))
1152 $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
1154 phpbb::$db->sql_freeresult($result);
1158 * Populate the module tables
1160 function add_modules($mode, $sub)
1162 include_once PHPBB_ROOT_PATH . 'modules/acp/acp_modules.' . PHP_EXT;
1164 $_module = new acp_modules();
1165 $module_classes = array('acp', 'mcp', 'ucp');
1167 // Add categories
1168 foreach ($module_classes as $module_class)
1170 $categories = array();
1172 // Set the module class
1173 $_module->module_class = $module_class;
1175 foreach ($this->module_categories[$module_class] as $cat_name => $subs)
1177 $module_data = array(
1178 'module_basename' => '',
1179 'module_enabled' => 1,
1180 'module_display' => 1,
1181 'parent_id' => 0,
1182 'module_class' => $module_class,
1183 'module_langname' => $cat_name,
1184 'module_mode' => '',
1185 'module_auth' => '',
1188 // Add category
1189 $_module->update_module_data($module_data, true);
1191 $categories[$cat_name]['id'] = (int) $module_data['module_id'];
1192 $categories[$cat_name]['parent_id'] = 0;
1194 // Create sub-categories...
1195 if (is_array($subs))
1197 foreach ($subs as $level2_name)
1199 $module_data = array(
1200 'module_basename' => '',
1201 'module_enabled' => 1,
1202 'module_display' => 1,
1203 'parent_id' => (int) $categories[$cat_name]['id'],
1204 'module_class' => $module_class,
1205 'module_langname' => $level2_name,
1206 'module_mode' => '',
1207 'module_auth' => '',
1210 $_module->update_module_data($module_data, true);
1212 $categories[$level2_name]['id'] = (int) $module_data['module_id'];
1213 $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id'];
1218 // Get the modules we want to add... returned sorted by name
1219 $module_info = $_module->get_module_infos('', $module_class);
1221 foreach ($module_info as $module_basename => $fileinfo)
1223 foreach ($fileinfo['modes'] as $module_mode => $row)
1225 foreach ($row['cat'] as $cat_name)
1227 if (!isset($categories[$cat_name]))
1229 continue;
1232 $module_data = array(
1233 'module_basename' => $module_basename,
1234 'module_enabled' => 1,
1235 'module_display' => (isset($row['display'])) ? (int) $row['display'] : 1,
1236 'parent_id' => (int) $categories[$cat_name]['id'],
1237 'module_class' => $module_class,
1238 'module_langname' => $row['title'],
1239 'module_mode' => $module_mode,
1240 'module_auth' => $row['auth'],
1243 $_module->update_module_data($module_data, true);
1248 // Move some of the modules around since the code above will put them in the wrong place
1249 if ($module_class == 'acp')
1251 // Move main module 4 up...
1252 $sql = 'SELECT *
1253 FROM ' . MODULES_TABLE . "
1254 WHERE module_basename = 'main'
1255 AND module_class = 'acp'
1256 AND module_mode = 'main'";
1257 $result = phpbb::$db->sql_query($sql);
1258 $row = phpbb::$db->sql_fetchrow($result);
1259 phpbb::$db->sql_freeresult($result);
1261 $_module->move_module_by($row, 'move_up', 4);
1263 // Move permissions intro screen module 4 up...
1264 $sql = 'SELECT *
1265 FROM ' . MODULES_TABLE . "
1266 WHERE module_basename = 'permissions'
1267 AND module_class = 'acp'
1268 AND module_mode = 'intro'";
1269 $result = phpbb::$db->sql_query($sql);
1270 $row = phpbb::$db->sql_fetchrow($result);
1271 phpbb::$db->sql_freeresult($result);
1273 $_module->move_module_by($row, 'move_up', 4);
1275 // Move manage users screen module 5 up...
1276 $sql = 'SELECT *
1277 FROM ' . MODULES_TABLE . "
1278 WHERE module_basename = 'users'
1279 AND module_class = 'acp'
1280 AND module_mode = 'overview'";
1281 $result = phpbb::$db->sql_query($sql);
1282 $row = phpbb::$db->sql_fetchrow($result);
1283 phpbb::$db->sql_freeresult($result);
1285 $_module->move_module_by($row, 'move_up', 5);
1288 if ($module_class == 'ucp')
1290 // Move attachment module 4 down...
1291 $sql = 'SELECT *
1292 FROM ' . MODULES_TABLE . "
1293 WHERE module_basename = 'attachments'
1294 AND module_class = 'ucp'
1295 AND module_mode = 'attachments'";
1296 $result = phpbb::$db->sql_query($sql);
1297 $row = phpbb::$db->sql_fetchrow($result);
1298 phpbb::$db->sql_freeresult($result);
1300 $_module->move_module_by($row, 'move_down', 4);
1303 // And now for the special ones
1304 // (these are modules which appear in multiple categories and thus get added manually to some for more control)
1305 if (isset($this->module_extras[$module_class]))
1307 foreach ($this->module_extras[$module_class] as $cat_name => $mods)
1309 $sql = 'SELECT module_id, left_id, right_id
1310 FROM ' . MODULES_TABLE . "
1311 WHERE module_langname = '" . phpbb::$db->sql_escape($cat_name) . "'
1312 AND module_class = '" . phpbb::$db->sql_escape($module_class) . "'";
1313 $result = phpbb::$db->sql_query_limit($sql, 1);
1314 $row2 = phpbb::$db->sql_fetchrow($result);
1315 phpbb::$db->sql_freeresult($result);
1317 foreach ($mods as $mod_name)
1319 $sql = 'SELECT *
1320 FROM ' . MODULES_TABLE . "
1321 WHERE module_langname = '" . phpbb::$db->sql_escape($mod_name) . "'
1322 AND module_class = '" . phpbb::$db->sql_escape($module_class) . "'
1323 AND module_basename <> ''";
1324 $result = phpbb::$db->sql_query_limit($sql, 1);
1325 $row = phpbb::$db->sql_fetchrow($result);
1326 phpbb::$db->sql_freeresult($result);
1328 $module_data = array(
1329 'module_basename' => $row['module_basename'],
1330 'module_enabled' => (int) $row['module_enabled'],
1331 'module_display' => (int) $row['module_display'],
1332 'parent_id' => (int) $row2['module_id'],
1333 'module_class' => $row['module_class'],
1334 'module_langname' => $row['module_langname'],
1335 'module_mode' => $row['module_mode'],
1336 'module_auth' => $row['module_auth'],
1339 $_module->update_module_data($module_data, true);
1344 $_module->remove_cache_file();
1349 * Populate the language tables
1351 function add_language($mode, $sub)
1353 $dir = @opendir(PHPBB_ROOT_PATH . 'language');
1355 if (!$dir)
1357 trigger_error('Unable to access the language directory', E_USER_ERROR);
1360 while (($file = readdir($dir)) !== false)
1362 $path = PHPBB_ROOT_PATH . 'language/' . $file;
1364 if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS')
1366 continue;
1369 if (is_dir($path) && file_exists($path . '/iso.txt'))
1371 $lang_file = file("$path/iso.txt");
1373 $lang_pack = array(
1374 'lang_iso' => basename($path),
1375 'lang_dir' => basename($path),
1376 'lang_english_name' => trim(htmlspecialchars($lang_file[0])),
1377 'lang_local_name' => trim(htmlspecialchars($lang_file[1], ENT_COMPAT, 'UTF-8')),
1378 'lang_author' => trim(htmlspecialchars($lang_file[2], ENT_COMPAT, 'UTF-8')),
1381 phpbb::$db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . phpbb::$db->sql_build_array('INSERT', $lang_pack));
1383 $valid_localized = array(
1384 'icon_back_top', 'icon_contact_aim', 'icon_contact_email', 'icon_contact_icq', 'icon_contact_jabber', 'icon_contact_msnm', 'icon_contact_pm', 'icon_contact_yahoo', 'icon_contact_www', 'icon_post_delete', 'icon_post_edit', 'icon_post_info', 'icon_post_quote', 'icon_post_report', 'icon_user_online', 'icon_user_offline', 'icon_user_profile', 'icon_user_search', 'icon_user_warn', 'button_pm_forward', 'button_pm_new', 'button_pm_reply', 'button_topic_locked', 'button_topic_new', 'button_topic_reply',
1387 $sql_ary = array();
1389 $sql = 'SELECT *
1390 FROM ' . STYLES_IMAGESET_TABLE;
1391 $result = phpbb::$db->sql_query($sql);
1393 while ($imageset_row = phpbb::$db->sql_fetchrow($result))
1395 if (@file_exists(PHPBB_ROOT_PATH . "styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['lang_iso']}/imageset.cfg"))
1397 $cfg_data_imageset_data = parse_cfg_file(PHPBB_ROOT_PATH . "styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['lang_iso']}/imageset.cfg");
1398 foreach ($cfg_data_imageset_data as $image_name => $value)
1400 if (strpos($value, '*') !== false)
1402 if (substr($value, -1, 1) === '*')
1404 list($image_filename, $image_height) = explode('*', $value);
1405 $image_width = 0;
1407 else
1409 list($image_filename, $image_height, $image_width) = explode('*', $value);
1412 else
1414 $image_filename = $value;
1415 $image_height = $image_width = 0;
1418 if (strpos($image_name, 'img_') === 0 && $image_filename)
1420 $image_name = substr($image_name, 4);
1421 if (in_array($image_name, $valid_localized))
1423 $sql_ary[] = array(
1424 'image_name' => (string) $image_name,
1425 'image_filename' => (string) $image_filename,
1426 'image_height' => (int) $image_height,
1427 'image_width' => (int) $image_width,
1428 'imageset_id' => (int) $imageset_row['imageset_id'],
1429 'image_lang' => (string) $lang_pack['lang_iso'],
1436 phpbb::$db->sql_freeresult($result);
1438 if (sizeof($sql_ary))
1440 phpbb::$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
1444 closedir($dir);
1448 * Add search robots to the database
1450 function add_bots($mode, $sub)
1452 $sql = 'SELECT group_id
1453 FROM ' . GROUPS_TABLE . "
1454 WHERE group_name_clean = 'bots'";
1455 $result = phpbb::$db->sql_query($sql);
1456 $group_id = (int) phpbb::$db->sql_fetchfield('group_id');
1457 phpbb::$db->sql_freeresult($result);
1459 if (!$group_id)
1461 // If we reach this point then something has gone very wrong
1462 trigger_error('NO_GROUP', E_USER_ERROR);
1465 if (!function_exists('user_add'))
1467 include PHPBB_ROOT_PATH . 'includes/functions_user.' . PHP_EXT;
1470 foreach ($this->bot_list as $bot_name => $bot_ary)
1472 $user_row = array(
1473 'user_type' => phpbb::USER_IGNORE,
1474 'group_id' => $group_id,
1475 'username' => $bot_name,
1476 'user_regdate' => time(),
1477 'user_password' => '',
1478 'user_colour' => '9E8DA7',
1479 'user_email' => '',
1480 'user_lang' => phpbb::$config['default_lang'],
1481 'user_style' => 1,
1482 'user_timezone' => 0,
1483 'user_dateformat' => phpbb::$user->lang['default_dateformat'],
1484 'user_allow_massemail' => 0,
1487 $user_id = user_add($user_row);
1489 if (!$user_id)
1491 // If we can't insert this user then continue to the next one to avoid inconsistant data
1492 $this->p_master->db_error('Unable to insert bot into users table', $db->sql_error_sql, __LINE__, __FILE__);
1493 continue;
1496 $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . phpbb::$db->sql_build_array('INSERT', array(
1497 'bot_active' => 1,
1498 'bot_name' => (string) $bot_name,
1499 'user_id' => (int) $user_id,
1500 'bot_agent' => (string) $bot_ary[0],
1501 'bot_ip' => (string) $bot_ary[1],
1504 $result = phpbb::$db->sql_query($sql);
1509 * Sends an email to the board administrator with their password and some useful links
1511 function email_admin($mode, $sub)
1513 // Obtain any submitted data
1514 $data = $this->get_submitted_data();
1516 // Normal Login
1517 phpbb::$user->login($data['admin_name'], $data['admin_pass1'], false, true, false);
1519 // Admin Login
1520 phpbb::$user->login($data['admin_name'], $data['admin_pass1'], false, true, true);
1522 phpbb::$acl->init(phpbb::$user->data);
1524 // OK, Now that we've reached this point we can be confident that everything is installed and working......I hope :)
1525 /* So it's time to send an email to the administrator confirming the details they entered
1526 if (phpbb::$config['email_enable'])
1528 include_once(PHPBB_ROOT_PATH . 'includes/functions_messenger.' . PHP_EXT);
1530 $messenger = new messenger(false);
1532 $messenger->template('installed', $data['language']);
1534 $messenger->to($data['board_contact'], $data['admin_name']);
1536 $messenger->headers('X-AntiAbuse: Board servername - ' . phpbb::$config['server_name']);
1537 $messenger->headers('X-AntiAbuse: User_id - ' . phpbb::$user->data['user_id']);
1538 $messenger->headers('X-AntiAbuse: Username - ' . phpbb::$user->data['username']);
1539 $messenger->headers('X-AntiAbuse: User IP - ' . phpbb::$user->ip);
1541 $messenger->assign_vars(array(
1542 'USERNAME' => htmlspecialchars_decode($data['admin_name']),
1543 'PASSWORD' => htmlspecialchars_decode($data['admin_pass1']))
1546 $messenger->send(NOTIFY_EMAIL);
1549 // And finally, add a note to the log
1550 add_log('admin', 'LOG_INSTALL_INSTALLED', phpbb::$config['version']);
1552 phpbb::$template->assign_vars(array(
1553 'L_BODY' => phpbb::$user->lang('INSTALL_CONGRATS_EXPLAIN', phpbb::$config['version'], phpbb::$url->append_sid('install/index', 'mode=convert&amp;language=' . $data['language']), '../docs/README.html'),
1554 'U_ACTION' => phpbb::$url->append_sid('adm/index'),
1559 * Generate a list of available mail server authentication methods
1561 function mail_auth_select($selected_method)
1563 $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP');
1564 $s_smtp_auth_options = '';
1566 foreach ($auth_methods as $method)
1568 $s_smtp_auth_options .= '<option value="' . $method . '"' . (($selected_method == $method) ? ' selected="selected"' : '') . '>' . phpbb::$user->lang['SMTP_' . str_replace('-', '_', $method)] . '</option>';
1571 return $s_smtp_auth_options;
1575 * Get submitted data
1577 function get_submitted_data()
1579 return array(
1580 'language' => basename(request_var('language', '')),
1581 'dbms' => request_var('dbms', ''),
1582 'dbhost' => request_var('dbhost', ''),
1583 'dbport' => request_var('dbport', ''),
1584 'dbuser' => request_var('dbuser', ''),
1585 'dbpasswd' => request_var('dbpasswd', '', true),
1586 'dbname' => request_var('dbname', ''),
1587 'table_prefix' => request_var('table_prefix', ''),
1588 'default_lang' => basename(request_var('default_lang', '')),
1589 'admin_name' => utf8_normalize_nfc(request_var('admin_name', '', true)),
1590 'admin_pass1' => request_var('admin_pass1', '', true),
1591 'admin_pass2' => request_var('admin_pass2', '', true),
1592 'board_email' => strtolower(request_var('board_email', '')),
1593 'board_contact' => strtolower(request_var('board_contact', '')),
1594 'img_imagick' => request_var('img_imagick', ''),
1595 'ftp_path' => request_var('ftp_path', ''),
1596 'ftp_user' => request_var('ftp_user', ''),
1597 'ftp_pass' => request_var('ftp_pass', ''),
1598 'email_enable' => request_var('email_enable', ''),
1599 'smtp_delivery' => request_var('smtp_delivery', ''),
1600 'smtp_host' => request_var('smtp_host', ''),
1601 'smtp_auth' => request_var('smtp_auth', ''),
1602 'smtp_user' => request_var('smtp_user', ''),
1603 'smtp_pass' => request_var('smtp_pass', ''),
1604 'cookie_secure' => request_var('cookie_secure', ''),
1605 'force_server_vars' => request_var('force_server_vars', ''),
1606 'server_protocol' => request_var('server_protocol', ''),
1607 'server_name' => request_var('server_name', ''),
1608 'server_port' => request_var('server_port', ''),
1609 'script_path' => request_var('script_path', ''),
1613 var $common_config_options = array('language' => array(), 'img_imagick' => array());
1616 * The information below will be used to build the input fields presented to the user
1618 var $db_config_options = array(
1619 'legend1' => 'DB_CONFIG',
1620 'dbms' => array('lang' => 'DBMS', 'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\')', 'explain' => false),
1621 'dbhost' => array('lang' => 'DB_HOST', 'type' => 'text:25:100', 'explain' => true),
1622 'dbport' => array('lang' => 'DB_PORT', 'type' => 'text:25:100', 'explain' => true),
1623 'dbname' => array('lang' => 'DB_NAME', 'type' => 'text:25:100', 'explain' => false),
1624 'dbuser' => array('lang' => 'DB_USERNAME', 'type' => 'text:25:100', 'explain' => false),
1625 'dbpasswd' => array('lang' => 'DB_PASSWORD', 'type' => 'password:25:100', 'explain' => false),
1626 'table_prefix' => array('lang' => 'TABLE_PREFIX', 'type' => 'text:25:100', 'explain' => false),
1628 var $admin_config_options = array(
1629 'legend1' => 'ADMIN_CONFIG',
1630 'default_lang' => array('lang' => 'DEFAULT_LANG', 'type' => 'select', 'options' => '$this->module->inst_language_select(\'{VALUE}\')', 'explain' => false),
1631 'admin_name' => array('lang' => 'ADMIN_USERNAME', 'type' => 'text:25:100', 'explain' => true),
1632 'admin_pass1' => array('lang' => 'ADMIN_PASSWORD', 'type' => 'password:25:100', 'explain' => true),
1633 'admin_pass2' => array('lang' => 'ADMIN_PASSWORD_CONFIRM', 'type' => 'password:25:100', 'explain' => false),
1634 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'type' => 'text:25:100', 'explain' => true),
1635 'board_email' => array('lang' => 'ADMIN_EMAIL', 'type' => 'text:25:100', 'explain' => true),
1637 var $advanced_config_options = array(
1638 'legend1' => 'ACP_EMAIL_SETTINGS',
1639 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'type' => 'radio:enabled_disabled', 'explain' => true),
1640 'smtp_delivery' => array('lang' => 'USE_SMTP', 'type' => 'radio:yes_no', 'explain' => true),
1641 'smtp_host' => array('lang' => 'SMTP_SERVER', 'type' => 'text:25:50', 'explain' => false),
1642 'smtp_auth' => array('lang' => 'SMTP_AUTH_METHOD', 'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true),
1643 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true),
1644 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true),
1646 'legend2' => 'SERVER_URL_SETTINGS',
1647 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'type' => 'radio:enabled_disabled', 'explain' => true),
1648 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'type' => 'radio:yes_no', 'explain' => true),
1649 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'type' => 'text:10:10', 'explain' => true),
1650 'server_name' => array('lang' => 'SERVER_NAME', 'type' => 'text:40:255', 'explain' => true),
1651 'server_port' => array('lang' => 'SERVER_PORT', 'type' => 'text:5:5', 'explain' => true),
1652 'script_path' => array('lang' => 'SCRIPT_PATH', 'type' => 'text::255', 'explain' => true),
1656 * Specific PHP modules we may require for certain optional or extended features
1658 var $php_dlls_other = array('zlib', 'ftp', 'gd', 'xml');
1661 * A list of the web-crawlers/bots we recognise by default
1663 * Candidates but not included:
1664 * 'Accoona [Bot]' 'Accoona-AI-Agent/'
1665 * 'ASPseek [Crawler]' 'ASPseek/'
1666 * 'Boitho [Crawler]' 'boitho.com-dc/'
1667 * 'Bunnybot [Bot]' 'powered by www.buncat.de'
1668 * 'Cosmix [Bot]' 'cfetch/'
1669 * 'Crawler Search [Crawler]' '.Crawler-Search.de'
1670 * 'Findexa [Crawler]' 'Findexa Crawler ('
1671 * 'GBSpider [Spider]' 'GBSpider v'
1672 * 'genie [Bot]' 'genieBot ('
1673 * 'Hogsearch [Bot]' 'oegp v. 1.3.0'
1674 * 'Insuranco [Bot]' 'InsurancoBot'
1675 * 'IRLbot [Bot]' 'http://irl.cs.tamu.edu/crawler'
1676 * 'ISC Systems [Bot]' 'ISC Systems iRc Search'
1677 * 'Jyxobot [Bot]' 'Jyxobot/'
1678 * 'Kraehe [Metasuche]' '-DIE-KRAEHE- META-SEARCH-ENGINE/'
1679 * 'LinkWalker' 'LinkWalker'
1680 * 'MMSBot [Bot]' 'http://www.mmsweb.at/bot.html'
1681 * 'Naver [Bot]' 'nhnbot@naver.com)'
1682 * 'NetResearchServer' 'NetResearchServer/'
1683 * 'Nimble [Crawler]' 'NimbleCrawler'
1684 * 'Ocelli [Bot]' 'Ocelli/'
1685 * 'Onsearch [Bot]' 'onCHECK-Robot'
1686 * 'Orange [Spider]' 'OrangeSpider'
1687 * 'Sproose [Bot]' 'http://www.sproose.com/bot'
1688 * 'Susie [Sync]' '!Susie (http://www.sync2it.com/susie)'
1689 * 'Tbot [Bot]' 'Tbot/'
1690 * 'Thumbshots [Capture]' 'thumbshots-de-Bot'
1691 * 'Vagabondo [Crawler]' 'http://webagent.wise-guys.nl/'
1692 * 'Walhello [Bot]' 'appie 1.1 (www.walhello.com)'
1693 * 'WissenOnline [Bot]' 'WissenOnline-Bot'
1694 * 'WWWeasel [Bot]' 'WWWeasel Robot v'
1695 * 'Xaldon [Spider]' 'Xaldon WebSpider'
1697 var $bot_list = array(
1698 'AdsBot [Google]' => array('AdsBot-Google', ''),
1699 'Alexa [Bot]' => array('ia_archiver', ''),
1700 'Alta Vista [Bot]' => array('Scooter/', ''),
1701 'Ask Jeeves [Bot]' => array('Ask Jeeves', ''),
1702 'Baidu [Spider]' => array('Baiduspider+(', ''),
1703 'Exabot [Bot]' => array('Exabot/', ''),
1704 'FAST Enterprise [Crawler]' => array('FAST Enterprise Crawler', ''),
1705 'FAST WebCrawler [Crawler]' => array('FAST-WebCrawler/', ''),
1706 'Francis [Bot]' => array('http://www.neomo.de/', ''),
1707 'Gigabot [Bot]' => array('Gigabot/', ''),
1708 'Google Adsense [Bot]' => array('Mediapartners-Google', ''),
1709 'Google Desktop' => array('Google Desktop', ''),
1710 'Google Feedfetcher' => array('Feedfetcher-Google', ''),
1711 'Google [Bot]' => array('Googlebot', ''),
1712 'Heise IT-Markt [Crawler]' => array('heise-IT-Markt-Crawler', ''),
1713 'Heritrix [Crawler]' => array('heritrix/1.', ''),
1714 'IBM Research [Bot]' => array('ibm.com/cs/crawler', ''),
1715 'ICCrawler - ICjobs' => array('ICCrawler - ICjobs', ''),
1716 'ichiro [Crawler]' => array('ichiro/2', ''),
1717 'Majestic-12 [Bot]' => array('MJ12bot/', ''),
1718 'Metager [Bot]' => array('MetagerBot/', ''),
1719 'MSN NewsBlogs' => array('msnbot-NewsBlogs/', ''),
1720 'MSN [Bot]' => array('msnbot/', ''),
1721 'MSNbot Media' => array('msnbot-media/', ''),
1722 'NG-Search [Bot]' => array('NG-Search/', ''),
1723 'Nutch [Bot]' => array('http://lucene.apache.org/nutch/', ''),
1724 'Nutch/CVS [Bot]' => array('NutchCVS/', ''),
1725 'OmniExplorer [Bot]' => array('OmniExplorer_Bot/', ''),
1726 'Online link [Validator]' => array('online link validator', ''),
1727 'psbot [Picsearch]' => array('psbot/0', ''),
1728 'Seekport [Bot]' => array('Seekbot/', ''),
1729 'Sensis [Crawler]' => array('Sensis Web Crawler', ''),
1730 'SEO Crawler' => array('SEO search Crawler/', ''),
1731 'Seoma [Crawler]' => array('Seoma [SEO Crawler]', ''),
1732 'SEOSearch [Crawler]' => array('SEOsearch/', ''),
1733 'Snappy [Bot]' => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
1734 'Steeler [Crawler]' => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
1735 'Synoo [Bot]' => array('SynooBot/', ''),
1736 'Telekom [Bot]' => array('crawleradmin.t-info@telekom.de', ''),
1737 'TurnitinBot [Bot]' => array('TurnitinBot/', ''),
1738 'Voyager [Bot]' => array('voyager/1.0', ''),
1739 'W3 [Sitesearch]' => array('W3 SiteSearch Crawler', ''),
1740 'W3C [Linkcheck]' => array('W3C-checklink/', ''),
1741 'W3C [Validator]' => array('W3C_*Validator', ''),
1742 'WiseNut [Bot]' => array('http://www.WISEnutbot.com', ''),
1743 'YaCy [Bot]' => array('yacybot', ''),
1744 'Yahoo MMCrawler [Bot]' => array('Yahoo-MMCrawler/', ''),
1745 'Yahoo Slurp [Bot]' => array('Yahoo! DE Slurp', ''),
1746 'Yahoo [Bot]' => array('Yahoo! Slurp', ''),
1747 'YahooSeeker [Bot]' => array('YahooSeeker/', ''),
1751 * Define the module structure so that we can populate the database without
1752 * needing to hard-code module_id values
1754 var $module_categories = array(
1755 'acp' => array(
1756 'ACP_CAT_GENERAL' => array(
1757 'ACP_QUICK_ACCESS',
1758 'ACP_BOARD_CONFIGURATION',
1759 'ACP_CLIENT_COMMUNICATION',
1760 'ACP_SERVER_CONFIGURATION',
1762 'ACP_CAT_FORUMS' => array(
1763 'ACP_MANAGE_FORUMS',
1764 'ACP_FORUM_BASED_PERMISSIONS',
1766 'ACP_CAT_POSTING' => array(
1767 'ACP_MESSAGES',
1768 'ACP_ATTACHMENTS',
1770 'ACP_CAT_USERGROUP' => array(
1771 'ACP_CAT_USERS',
1772 'ACP_GROUPS',
1773 'ACP_USER_SECURITY',
1775 'ACP_CAT_PERMISSIONS' => array(
1776 'ACP_GLOBAL_PERMISSIONS',
1777 'ACP_FORUM_BASED_PERMISSIONS',
1778 'ACP_PERMISSION_ROLES',
1779 'ACP_PERMISSION_MASKS',
1781 'ACP_CAT_STYLES' => array(
1782 'ACP_STYLE_MANAGEMENT',
1783 'ACP_STYLE_COMPONENTS',
1785 'ACP_CAT_MAINTENANCE' => array(
1786 'ACP_FORUM_LOGS',
1787 'ACP_CAT_DATABASE',
1789 'ACP_CAT_SYSTEM' => array(
1790 'ACP_AUTOMATION',
1791 'ACP_GENERAL_TASKS',
1792 'ACP_MODULE_MANAGEMENT',
1794 'ACP_CAT_DOT_MODS' => null,
1796 'mcp' => array(
1797 'MCP_MAIN' => null,
1798 'MCP_QUEUE' => null,
1799 'MCP_REPORTS' => null,
1800 'MCP_NOTES' => null,
1801 'MCP_WARN' => null,
1802 'MCP_LOGS' => null,
1803 'MCP_BAN' => null,
1805 'ucp' => array(
1806 'UCP_MAIN' => null,
1807 'UCP_PROFILE' => null,
1808 'UCP_PREFS' => null,
1809 'UCP_PM' => null,
1810 'UCP_USERGROUPS' => null,
1811 'UCP_ZEBRA' => null,
1815 var $module_extras = array(
1816 'acp' => array(
1817 'ACP_QUICK_ACCESS' => array(
1818 'ACP_MANAGE_USERS',
1819 'ACP_GROUPS_MANAGE',
1820 'ACP_MANAGE_FORUMS',
1821 'ACP_MOD_LOGS',
1822 'ACP_BOTS',
1823 'ACP_PHP_INFO',
1825 'ACP_FORUM_BASED_PERMISSIONS' => array(
1826 'ACP_FORUM_PERMISSIONS',
1827 'ACP_FORUM_MODERATORS',
1828 'ACP_USERS_FORUM_PERMISSIONS',
1829 'ACP_GROUPS_FORUM_PERMISSIONS',
1834 var $role_definitions = array(
1835 // Standard Admin (a_)
1836 array('ROLE_ADMIN_STANDARD', 1, 'a_', 'NOT IN', array('a_switchperm', 'a_jabber', 'a_phpinfo', 'a_server', 'a_backup', 'a_styles', 'a_clearlogs', 'a_modules', 'a_language', 'a_email', 'a_bots', 'a_search', 'a_aauth', 'a_roles')),
1837 // Forum Admin (a_)
1838 array('ROLE_ADMIN_FORUM', 1, 'a_', 'IN', array('a_', 'a_authgroups', 'a_authusers', 'a_fauth', 'a_forum', 'a_forumadd', 'a_forumdel', 'a_mauth', 'a_prune', 'a_uauth', 'a_viewauth', 'a_viewlogs')),
1839 // User and Groups Admin (a_)
1840 array('ROLE_ADMIN_USERGROUP', 1, 'a_', 'IN', array('a_', 'a_authgroups', 'a_authusers', 'a_ban', 'a_group', 'a_groupadd', 'a_groupdel', 'a_ranks', 'a_uauth', 'a_user', 'a_viewauth', 'a_viewlogs')),
1841 // Full Admin (a_)
1842 array('ROLE_ADMIN_FULL', 1, 'a_', false, false),
1843 // All Features (u_)
1844 array('ROLE_USER_FULL', 1, 'u_', false, false),
1845 // Standard Features (u_)
1846 array('ROLE_USER_STANDARD', 1, 'u_', 'NOT IN', array('u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_flash', 'u_pm_forward')),
1847 // Limited Features (u_)
1848 array('ROLE_USER_LIMITED', 1, 'u_', 'NOT IN', array('u_attach', 'u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_attach', 'u_pm_emailpm', 'u_pm_flash', 'u_savedrafts', 'u_search', 'u_sendemail', 'u_sendim', 'u_masspm', 'u_masspm_group')),
1849 // No Private Messages (u_)
1850 array('ROLE_USER_NOPM', 1, 'u_', 'IN', array('u_', 'u_chgavatar', 'u_chgcensors', 'u_chgemail', 'u_chgpasswd', 'u_download', 'u_hideonline', 'u_sig', 'u_viewprofile')),
1851 array('ROLE_USER_NOPM', 0, 'u_', 'IN', array('u_readpm', 'u_sendpm', 'u_masspm', 'u_masspm_group')),
1852 // No Avatar (u_)
1853 array('ROLE_USER_NOAVATAR', 1, 'u_', 'NOT IN', array('u_attach', 'u_chgavatar', 'u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_attach', 'u_pm_emailpm', 'u_pm_flash', 'u_savedrafts', 'u_search', 'u_sendemail', 'u_sendim', 'u_masspm', 'u_masspm_group')),
1854 array('ROLE_USER_NOAVATAR', 0, 'u_', 'IN', array('u_chgavatar', 'u_masspm', 'u_masspm_group')),
1855 // Download and search for guests (u_)
1856 array('ROLE_USER_GUESTS', 1, 'u_', 'IN', array('u_', 'u_download', 'u_search')),
1857 // Full Moderator (m_)
1858 array('ROLE_MOD_FULL', 1, 'm_', false, false),
1859 // Standard Moderator (m_)
1860 array('ROLE_MOD_STANDARD', 1, 'm_', 'NOT IN', array('m_ban', 'm_chgposter')),
1861 // Simple Moderator (m_)
1862 array('ROLE_MOD_SIMPLE', 1, 'm_', 'IN', array('m_', 'm_delete', 'm_edit', 'm_info', 'm_report')),
1863 // Queue Moderator (m_)
1864 array('ROLE_MOD_QUEUE', 1, 'm_', 'IN', array('m_', 'm_approve', 'm_edit')),
1865 // Full Access (f_)
1866 array('ROLE_FORUM_FULL', 1, 'f_', false, false),
1867 // Standard Access (f_)
1868 array('ROLE_FORUM_STANDARD', 1, 'f_', 'NOT IN', array('f_announce', 'f_flash', 'f_ignoreflood', 'f_poll', 'f_sticky', 'f_user_lock')),
1869 // No Access (f_)
1870 array('ROLE_FORUM_NOACCESS', 0, 'f_', 'IN', array('f_')),
1871 // Read Only Access (f_)
1872 array('ROLE_FORUM_READONLY', 1, 'f_', 'IN', array('f_', 'f_download', 'f_list', 'f_read', 'f_search', 'f_subscribe', 'f_print')),
1873 // Limited Access (f_)
1874 array('ROLE_FORUM_LIMITED', 1, 'f_', 'NOT IN', array('f_announce', 'f_attach', 'f_bump', 'f_delete', 'f_flash', 'f_icons', 'f_ignoreflood', 'f_poll', 'f_sticky', 'f_user_lock', 'f_votechg')),
1875 // Bot Access (f_)
1876 array('ROLE_FORUM_BOT', 1, 'f_', 'IN', array('f_', 'f_download', 'f_list', 'f_read', 'f_print')),
1877 // On Moderation Queue (f_)
1878 array('ROLE_FORUM_ONQUEUE', 1, 'f_', 'NOT IN', array('f_announce', 'f_bump', 'f_delete', 'f_flash', 'f_icons', 'f_ignoreflood', 'f_poll', 'f_sticky', 'f_user_lock', 'f_votechg', 'f_noapprove')),
1879 array('ROLE_FORUM_ONQUEUE', 0, 'f_', 'IN', array('f_noapprove')),
1880 // Standard Access + Polls (f_)
1881 array('ROLE_FORUM_POLLS', 1, 'f_', 'NOT IN', array('f_announce', 'f_flash', 'f_ignoreflood', 'f_sticky', 'f_user_lock')),
1882 // Limited Access + Polls (f_)
1883 array('ROLE_FORUM_LIMITED_POLLS', 1, 'f_', 'NOT IN', array('f_announce', 'f_attach', 'f_bump', 'f_delete', 'f_flash', 'f_icons', 'f_ignoreflood', 'f_sticky', 'f_user_lock', 'f_votechg')),