(a little test for later merges)
[phpbb.git] / phpBB / install / install_install.php
blob1b8553fb7a189232ab18b9ec8b9d9d2b2776e549
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.' . $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock'))
24 include_once($phpbb_root_path . 'config.' . $phpEx);
26 if (defined('PHPBB_INSTALLED'))
28 return;
32 $module[] = array(
33 'module_type' => 'install',
34 'module_title' => 'INSTALL',
35 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-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 global $lang, $template, $language, $phpbb_root_path;
58 switch ($sub)
60 case 'intro':
61 $this->page_title = $lang['SUB_INTRO'];
63 $template->assign_vars(array(
64 'TITLE' => $lang['INSTALL_INTRO'],
65 'BODY' => $lang['INSTALL_INTRO_BODY'],
66 'L_SUBMIT' => $lang['NEXT_STEP'],
67 'S_LANG_SELECT' => '<select id="language" name="language">' . $this->p_master->inst_language_select($language) . '</select>',
68 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language",
69 ));
71 break;
73 case 'requirements':
74 $this->check_server_requirements($mode, $sub);
76 break;
78 case 'database':
79 $this->obtain_database_settings($mode, $sub);
81 break;
83 case 'administrator':
84 $this->obtain_admin_settings($mode, $sub);
86 break;
88 case 'config_file':
89 $this->create_config_file($mode, $sub);
91 break;
93 case 'advanced':
94 $this->obtain_advanced_settings($mode, $sub);
96 break;
98 case 'create_table':
99 $this->load_schema($mode, $sub);
100 break;
102 case 'final':
103 $this->build_search_index($mode, $sub);
104 $this->add_modules($mode, $sub);
105 $this->add_language($mode, $sub);
106 $this->add_bots($mode, $sub);
107 $this->email_admin($mode, $sub);
109 // Remove the lock file
110 @unlink($phpbb_root_path . 'cache/install_lock');
112 break;
115 $this->tpl_name = 'install_install';
119 * Checks that the server we are installing on meets the requirements for running phpBB
121 function check_server_requirements($mode, $sub)
123 global $lang, $template, $phpbb_root_path, $phpEx, $language;
125 $this->page_title = $lang['STAGE_REQUIREMENTS'];
127 $template->assign_vars(array(
128 'TITLE' => $lang['REQUIREMENTS_TITLE'],
129 'BODY' => $lang['REQUIREMENTS_EXPLAIN'],
132 $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false,);
134 // Test for basic PHP settings
135 $template->assign_block_vars('checks', array(
136 'S_LEGEND' => true,
137 'LEGEND' => $lang['PHP_SETTINGS'],
138 'LEGEND_EXPLAIN' => $lang['PHP_SETTINGS_EXPLAIN'],
141 // Test the minimum PHP version
142 $php_version = PHP_VERSION;
144 if (version_compare($php_version, '4.3.3') < 0)
146 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
148 else
150 $passed['php'] = true;
152 // We also give feedback on whether we're running in safe mode
153 $result = '<strong style="color:green">' . $lang['YES'];
154 if (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) == 'on')
156 $result .= ', ' . $lang['PHP_SAFE_MODE'];
158 $result .= '</strong>';
161 $template->assign_block_vars('checks', array(
162 'TITLE' => $lang['PHP_VERSION_REQD'],
163 'RESULT' => $result,
165 'S_EXPLAIN' => false,
166 'S_LEGEND' => false,
169 // Check for register_globals being enabled
170 if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on')
172 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
174 else
176 $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
179 $template->assign_block_vars('checks', array(
180 'TITLE' => $lang['PHP_REGISTER_GLOBALS'],
181 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'],
182 'RESULT' => $result,
184 'S_EXPLAIN' => true,
185 'S_LEGEND' => false,
189 // Check for url_fopen
190 if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on')
192 $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
194 else
196 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
199 $template->assign_block_vars('checks', array(
200 'TITLE' => $lang['PHP_URL_FOPEN_SUPPORT'],
201 'TITLE_EXPLAIN' => $lang['PHP_URL_FOPEN_SUPPORT_EXPLAIN'],
202 'RESULT' => $result,
204 'S_EXPLAIN' => true,
205 'S_LEGEND' => false,
209 // Check for getimagesize
210 if (@function_exists('getimagesize'))
212 $passed['imagesize'] = true;
213 $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
215 else
217 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
220 $template->assign_block_vars('checks', array(
221 'TITLE' => $lang['PHP_GETIMAGESIZE_SUPPORT'],
222 'TITLE_EXPLAIN' => $lang['PHP_GETIMAGESIZE_SUPPORT_EXPLAIN'],
223 'RESULT' => $result,
225 'S_EXPLAIN' => true,
226 'S_LEGEND' => false,
229 // Check for PCRE UTF-8 support
230 if (@preg_match('//u', ''))
232 $passed['pcre'] = true;
233 $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
235 else
237 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
240 $template->assign_block_vars('checks', array(
241 'TITLE' => $lang['PCRE_UTF_SUPPORT'],
242 'TITLE_EXPLAIN' => $lang['PCRE_UTF_SUPPORT_EXPLAIN'],
243 'RESULT' => $result,
245 'S_EXPLAIN' => true,
246 'S_LEGEND' => false,
250 * Better not enabling and adding to the loaded extensions due to the specific requirements needed
251 if (!@extension_loaded('mbstring'))
253 can_load_dll('mbstring');
257 $passed['mbstring'] = true;
258 if (@extension_loaded('mbstring'))
260 // Test for available database modules
261 $template->assign_block_vars('checks', array(
262 'S_LEGEND' => true,
263 'LEGEND' => $lang['MBSTRING_CHECK'],
264 'LEGEND_EXPLAIN' => $lang['MBSTRING_CHECK_EXPLAIN'],
267 $checks = array(
268 array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING),
269 array('encoding_translation', '!=', 0),
270 array('http_input', '!=', 'pass'),
271 array('http_output', '!=', 'pass')
274 foreach ($checks as $mb_checks)
276 $ini_val = @ini_get('mbstring.' . $mb_checks[0]);
277 switch ($mb_checks[1])
279 case '&':
280 if (intval($ini_val) & $mb_checks[2])
282 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
283 $passed['mbstring'] = false;
285 else
287 $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
289 break;
291 case '!=':
292 if ($ini_val != $mb_checks[2])
294 $result = '<strong style="color:red">' . $lang['NO'] . '</strong>';
295 $passed['mbstring'] = false;
297 else
299 $result = '<strong style="color:green">' . $lang['YES'] . '</strong>';
301 break;
303 $template->assign_block_vars('checks', array(
304 'TITLE' => $lang['MBSTRING_' . strtoupper($mb_checks[0])],
305 'TITLE_EXPLAIN' => $lang['MBSTRING_' . strtoupper($mb_checks[0]) . '_EXPLAIN'],
306 'RESULT' => $result,
308 'S_EXPLAIN' => true,
309 'S_LEGEND' => false,
314 // Test for available database modules
315 $template->assign_block_vars('checks', array(
316 'S_LEGEND' => true,
317 'LEGEND' => $lang['PHP_SUPPORTED_DB'],
318 'LEGEND_EXPLAIN' => $lang['PHP_SUPPORTED_DB_EXPLAIN'],
321 $available_dbms = get_available_dbms(false, true);
322 $passed['db'] = $available_dbms['ANY_DB_SUPPORT'];
323 unset($available_dbms['ANY_DB_SUPPORT']);
325 foreach ($available_dbms as $db_name => $db_ary)
327 if (!$db_ary['AVAILABLE'])
329 $template->assign_block_vars('checks', array(
330 'TITLE' => $lang['DLL_' . strtoupper($db_name)],
331 'RESULT' => '<span style="color:red">' . $lang['UNAVAILABLE'] . '</span>',
333 'S_EXPLAIN' => false,
334 'S_LEGEND' => false,
337 else
339 $template->assign_block_vars('checks', array(
340 'TITLE' => $lang['DLL_' . strtoupper($db_name)],
341 'RESULT' => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
343 'S_EXPLAIN' => false,
344 'S_LEGEND' => false,
349 // Test for other modules
350 $template->assign_block_vars('checks', array(
351 'S_LEGEND' => true,
352 'LEGEND' => $lang['PHP_OPTIONAL_MODULE'],
353 'LEGEND_EXPLAIN' => $lang['PHP_OPTIONAL_MODULE_EXPLAIN'],
356 foreach ($this->php_dlls_other as $dll)
358 if (!@extension_loaded($dll))
360 if (!can_load_dll($dll))
362 $template->assign_block_vars('checks', array(
363 'TITLE' => $lang['DLL_' . strtoupper($dll)],
364 'RESULT' => '<strong style="color:red">' . $lang['UNAVAILABLE'] . '</strong>',
366 'S_EXPLAIN' => false,
367 'S_LEGEND' => false,
369 continue;
373 $template->assign_block_vars('checks', array(
374 'TITLE' => $lang['DLL_' . strtoupper($dll)],
375 'RESULT' => '<strong style="color:green">' . $lang['AVAILABLE'] . '</strong>',
377 'S_EXPLAIN' => false,
378 'S_LEGEND' => false,
382 // Can we find Imagemagick anywhere on the system?
383 $exe = (DIRECTORY_SEPARATOR == '\\') ? '.exe' : '';
385 $magic_home = getenv('MAGICK_HOME');
386 $img_imagick = '';
387 if (empty($magic_home))
389 $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/');
390 $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH'))));
392 $locations = array_merge($path_locations, $locations);
393 foreach ($locations as $location)
395 // The path might not end properly, fudge it
396 if (substr($location, -1, 1) !== '/')
398 $location .= '/';
401 if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000)
403 $img_imagick = str_replace('\\', '/', $location);
404 continue;
408 else
410 $img_imagick = str_replace('\\', '/', $magic_home);
413 $template->assign_block_vars('checks', array(
414 'TITLE' => $lang['APP_MAGICK'],
415 'RESULT' => ($img_imagick) ? '<strong style="color:green">' . $lang['AVAILABLE'] . ', ' . $img_imagick . '</strong>' : '<strong style="color:blue">' . $lang['NO_LOCATION'] . '</strong>',
417 'S_EXPLAIN' => false,
418 'S_LEGEND' => false,
421 // Check permissions on files/directories we need access to
422 $template->assign_block_vars('checks', array(
423 'S_LEGEND' => true,
424 'LEGEND' => $lang['FILES_REQUIRED'],
425 'LEGEND_EXPLAIN' => $lang['FILES_REQUIRED_EXPLAIN'],
428 $directories = array('cache/', 'files/', 'store/');
430 umask(0);
432 $passed['files'] = true;
433 foreach ($directories as $dir)
435 $exists = $write = false;
437 // Try to create the directory if it does not exist
438 if (!file_exists($phpbb_root_path . $dir))
440 @mkdir($phpbb_root_path . $dir, 0777);
441 phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
444 // Now really check
445 if (file_exists($phpbb_root_path . $dir) && is_dir($phpbb_root_path . $dir))
447 phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE);
448 $exists = true;
451 // Now check if it is writable by storing a simple file
452 $fp = @fopen($phpbb_root_path . $dir . 'test_lock', 'wb');
453 if ($fp !== false)
455 $write = true;
457 @fclose($fp);
459 @unlink($phpbb_root_path . $dir . 'test_lock');
461 $passed['files'] = ($exists && $write && $passed['files']) ? true : false;
463 $exists = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
464 $write = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
466 $template->assign_block_vars('checks', array(
467 'TITLE' => $dir,
468 'RESULT' => $exists . $write,
470 'S_EXPLAIN' => false,
471 'S_LEGEND' => false,
475 // Check permissions on files/directories it would be useful access to
476 $template->assign_block_vars('checks', array(
477 'S_LEGEND' => true,
478 'LEGEND' => $lang['FILES_OPTIONAL'],
479 'LEGEND_EXPLAIN' => $lang['FILES_OPTIONAL_EXPLAIN'],
482 $directories = array('config.' . $phpEx, 'images/avatars/upload/');
484 foreach ($directories as $dir)
486 $write = $exists = true;
487 if (file_exists($phpbb_root_path . $dir))
489 if (!@is_writable($phpbb_root_path . $dir))
491 $write = false;
494 else
496 $write = $exists = false;
499 $exists_str = ($exists) ? '<strong style="color:green">' . $lang['FOUND'] . '</strong>' : '<strong style="color:red">' . $lang['NOT_FOUND'] . '</strong>';
500 $write_str = ($write) ? ', <strong style="color:green">' . $lang['WRITABLE'] . '</strong>' : (($exists) ? ', <strong style="color:red">' . $lang['UNWRITABLE'] . '</strong>' : '');
502 $template->assign_block_vars('checks', array(
503 'TITLE' => $dir,
504 'RESULT' => $exists_str . $write_str,
506 'S_EXPLAIN' => false,
507 'S_LEGEND' => false,
511 // And finally where do we want to go next (well today is taken isn't it :P)
512 $s_hidden_fields = ($img_imagick) ? '<input type="hidden" name="img_imagick" value="' . addslashes($img_imagick) . '" />' : '';
514 $url = (!in_array(false, $passed)) ? $this->p_master->module_url . "?mode=$mode&amp;sub=database&amp;language=$language" : $this->p_master->module_url . "?mode=$mode&amp;sub=requirements&amp;language=$language ";
515 $submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST'];
518 $template->assign_vars(array(
519 'L_SUBMIT' => $submit,
520 'S_HIDDEN' => $s_hidden_fields,
521 'U_ACTION' => $url,
526 * Obtain the information required to connect to the database
528 function obtain_database_settings($mode, $sub)
530 global $lang, $template, $phpEx;
532 $this->page_title = $lang['STAGE_DATABASE'];
534 // Obtain any submitted data
535 $data = $this->get_submitted_data();
537 $connect_test = false;
538 $error = array();
539 $available_dbms = get_available_dbms(false, true);
541 // Has the user opted to test the connection?
542 if (isset($_POST['testdb']))
544 if (!isset($available_dbms[$data['dbms']]) || !$available_dbms[$data['dbms']]['AVAILABLE'])
546 $error[] = $lang['INST_ERR_NO_DB'];
547 $connect_test = false;
549 else
551 $connect_test = connect_check_db(true, $error, $available_dbms[$data['dbms']], $data['table_prefix'], $data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport']);
554 $template->assign_block_vars('checks', array(
555 'S_LEGEND' => true,
556 'LEGEND' => $lang['DB_CONNECTION'],
557 'LEGEND_EXPLAIN' => false,
560 if ($connect_test)
562 $template->assign_block_vars('checks', array(
563 'TITLE' => $lang['DB_TEST'],
564 'RESULT' => '<strong style="color:green">' . $lang['SUCCESSFUL_CONNECT'] . '</strong>',
566 'S_EXPLAIN' => false,
567 'S_LEGEND' => false,
570 else
572 $template->assign_block_vars('checks', array(
573 'TITLE' => $lang['DB_TEST'],
574 'RESULT' => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
576 'S_EXPLAIN' => false,
577 'S_LEGEND' => false,
582 if (!$connect_test)
584 // Update the list of available DBMS modules to only contain those which can be used
585 $available_dbms_temp = array();
586 foreach ($available_dbms as $type => $dbms_ary)
588 if (!$dbms_ary['AVAILABLE'])
590 continue;
593 $available_dbms_temp[$type] = $dbms_ary;
596 $available_dbms = &$available_dbms_temp;
598 // And now for the main part of this page
599 $data['table_prefix'] = (!empty($data['table_prefix']) ? $data['table_prefix'] : 'phpbb_');
601 foreach ($this->db_config_options as $config_key => $vars)
603 if (!is_array($vars) && strpos($config_key, 'legend') === false)
605 continue;
608 if (strpos($config_key, 'legend') !== false)
610 $template->assign_block_vars('options', array(
611 'S_LEGEND' => true,
612 'LEGEND' => $lang[$vars])
615 continue;
618 $options = isset($vars['options']) ? $vars['options'] : '';
620 $template->assign_block_vars('options', array(
621 'KEY' => $config_key,
622 'TITLE' => $lang[$vars['lang']],
623 'S_EXPLAIN' => $vars['explain'],
624 'S_LEGEND' => false,
625 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
626 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
632 // And finally where do we want to go next (well today is taken isn't it :P)
633 $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
634 $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
635 if ($connect_test)
637 foreach ($this->db_config_options as $config_key => $vars)
639 if (!is_array($vars))
641 continue;
643 $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
647 $url = ($connect_test) ? $this->p_master->module_url . "?mode=$mode&amp;sub=administrator" : $this->p_master->module_url . "?mode=$mode&amp;sub=database";
648 $s_hidden_fields .= ($connect_test) ? '' : '<input type="hidden" name="testdb" value="true" />';
650 $submit = $lang['NEXT_STEP'];
652 $template->assign_vars(array(
653 'L_SUBMIT' => $submit,
654 'S_HIDDEN' => $s_hidden_fields,
655 'U_ACTION' => $url,
660 * Obtain the administrator's name, password and email address
662 function obtain_admin_settings($mode, $sub)
664 global $lang, $template, $phpEx;
666 $this->page_title = $lang['STAGE_ADMINISTRATOR'];
668 // Obtain any submitted data
669 $data = $this->get_submitted_data();
671 if ($data['dbms'] == '')
673 // Someone's been silly and tried calling this page direct
674 // So we send them back to the start to do it again properly
675 $this->p_master->redirect("index.$phpEx?mode=install");
678 $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
679 $passed = false;
681 $data['default_lang'] = ($data['default_lang'] !== '') ? $data['default_lang'] : $data['language'];
683 if (isset($_POST['check']))
685 $error = array();
687 // Check the entered email address and password
688 if ($data['admin_name'] == '' || $data['admin_pass1'] == '' || $data['admin_pass2'] == '' || $data['board_email1'] == '' || $data['board_email2'] == '')
690 $error[] = $lang['INST_ERR_MISSING_DATA'];
693 if ($data['admin_pass1'] != $data['admin_pass2'] && $data['admin_pass1'] != '')
695 $error[] = $lang['INST_ERR_PASSWORD_MISMATCH'];
698 // Test against the default username rules
699 if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) < 3)
701 $error[] = $lang['INST_ERR_USER_TOO_SHORT'];
704 if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) > 20)
706 $error[] = $lang['INST_ERR_USER_TOO_LONG'];
709 // Test against the default password rules
710 if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) < 6)
712 $error[] = $lang['INST_ERR_PASSWORD_TOO_SHORT'];
715 if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) > 30)
717 $error[] = $lang['INST_ERR_PASSWORD_TOO_LONG'];
720 if ($data['board_email1'] != $data['board_email2'] && $data['board_email1'] != '')
722 $error[] = $lang['INST_ERR_EMAIL_MISMATCH'];
725 if ($data['board_email1'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_email1']))
727 $error[] = $lang['INST_ERR_EMAIL_INVALID'];
730 $template->assign_block_vars('checks', array(
731 'S_LEGEND' => true,
732 'LEGEND' => $lang['STAGE_ADMINISTRATOR'],
733 'LEGEND_EXPLAIN' => false,
736 if (!sizeof($error))
738 $passed = true;
739 $template->assign_block_vars('checks', array(
740 'TITLE' => $lang['ADMIN_TEST'],
741 'RESULT' => '<strong style="color:green">' . $lang['TESTS_PASSED'] . '</strong>',
743 'S_EXPLAIN' => false,
744 'S_LEGEND' => false,
747 else
749 $template->assign_block_vars('checks', array(
750 'TITLE' => $lang['ADMIN_TEST'],
751 'RESULT' => '<strong style="color:red">' . implode('<br />', $error) . '</strong>',
753 'S_EXPLAIN' => false,
754 'S_LEGEND' => false,
759 if (!$passed)
761 foreach ($this->admin_config_options as $config_key => $vars)
763 if (!is_array($vars) && strpos($config_key, 'legend') === false)
765 continue;
768 if (strpos($config_key, 'legend') !== false)
770 $template->assign_block_vars('options', array(
771 'S_LEGEND' => true,
772 'LEGEND' => $lang[$vars])
775 continue;
778 $options = isset($vars['options']) ? $vars['options'] : '';
780 $template->assign_block_vars('options', array(
781 'KEY' => $config_key,
782 'TITLE' => $lang[$vars['lang']],
783 'S_EXPLAIN' => $vars['explain'],
784 'S_LEGEND' => false,
785 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
786 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
791 else
793 foreach ($this->admin_config_options as $config_key => $vars)
795 if (!is_array($vars))
797 continue;
799 $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
803 $s_hidden_fields .= ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
804 $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
806 foreach ($this->db_config_options as $config_key => $vars)
808 if (!is_array($vars))
810 continue;
812 $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
815 $submit = $lang['NEXT_STEP'];
817 $url = ($passed) ? $this->p_master->module_url . "?mode=$mode&amp;sub=config_file" : $this->p_master->module_url . "?mode=$mode&amp;sub=administrator";
818 $s_hidden_fields .= ($passed) ? '' : '<input type="hidden" name="check" value="true" />';
820 $template->assign_vars(array(
821 'L_SUBMIT' => $submit,
822 'S_HIDDEN' => $s_hidden_fields,
823 'U_ACTION' => $url,
828 * Writes the config file to disk, or if unable to do so offers alternative methods
830 function create_config_file($mode, $sub)
832 global $lang, $template, $phpbb_root_path, $phpEx;
834 $this->page_title = $lang['STAGE_CONFIG_FILE'];
836 // Obtain any submitted data
837 $data = $this->get_submitted_data();
839 if ($data['dbms'] == '')
841 // Someone's been silly and tried calling this page direct
842 // So we send them back to the start to do it again properly
843 $this->p_master->redirect("index.$phpEx?mode=install");
846 $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
847 $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
848 $written = false;
850 // Create a list of any PHP modules we wish to have loaded
851 $load_extensions = array();
852 $available_dbms = get_available_dbms($data['dbms']);
853 $check_exts = array_merge(array($available_dbms[$data['dbms']]['MODULE']), $this->php_dlls_other);
855 foreach ($check_exts as $dll)
857 if (!@extension_loaded($dll))
859 if (!can_load_dll($dll))
861 continue;
864 $load_extensions[] = $dll . '.' . PHP_SHLIB_SUFFIX;
868 // Create a lock file to indicate that there is an install in progress
869 $fp = @fopen($phpbb_root_path . 'cache/install_lock', 'wb');
870 if ($fp === false)
872 // We were unable to create the lock file - abort
873 $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__);
875 @fclose($fp);
877 @chmod($phpbb_root_path . 'cache/install_lock', 0777);
879 $load_extensions = implode(',', $load_extensions);
881 // Time to convert the data provided into a config file
882 $config_data = "<?php\n";
883 $config_data .= "// phpBB 3.0.x auto-generated configuration file\n// Do not change anything in this file!\n";
885 $config_data_array = array(
886 'dbms' => $available_dbms[$data['dbms']]['DRIVER'],
887 'dbhost' => $data['dbhost'],
888 'dbport' => $data['dbport'],
889 'dbname' => $data['dbname'],
890 'dbuser' => $data['dbuser'],
891 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']),
892 'table_prefix' => $data['table_prefix'],
893 'acm_type' => 'file',
894 'load_extensions' => $load_extensions,
897 foreach ($config_data_array as $key => $value)
899 $config_data .= "\${$key} = '" . str_replace("'", "\\'", str_replace('\\', '\\\\', $value)) . "';\n";
901 unset($config_data_array);
903 $config_data .= "\n@define('PHPBB_INSTALLED', true);\n";
904 $config_data .= "// @define('DEBUG', true);\n";
905 $config_data .= "// @define('DEBUG_EXTRA', true);\n";
906 $config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused!
908 // Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
909 if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && is_writable($phpbb_root_path . 'config.' . $phpEx)) || is_writable($phpbb_root_path))
911 // Assume it will work ... if nothing goes wrong below
912 $written = true;
914 if (!($fp = @fopen($phpbb_root_path . 'config.' . $phpEx, 'w')))
916 // Something went wrong ... so let's try another method
917 $written = false;
920 if (!(@fwrite($fp, $config_data)))
922 // Something went wrong ... so let's try another method
923 $written = false;
926 @fclose($fp);
928 if ($written)
930 // We may revert back to chmod() if we see problems with users not able to change their config.php file directly
931 phpbb_chmod($phpbb_root_path . 'config.' . $phpEx, CHMOD_READ);
935 if (isset($_POST['dldone']))
937 // Do a basic check to make sure that the file has been uploaded
938 // Note that all we check is that the file has _something_ in it
939 // We don't compare the contents exactly - if they can't upload
940 // a single file correctly, it's likely they will have other problems....
941 if (filesize($phpbb_root_path . 'config.' . $phpEx) > 10)
943 $written = true;
947 $config_options = array_merge($this->db_config_options, $this->admin_config_options);
949 foreach ($config_options as $config_key => $vars)
951 if (!is_array($vars))
953 continue;
955 $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
958 if (!$written)
960 // OK, so it didn't work let's try the alternatives
962 if (isset($_POST['dlconfig']))
964 // They want a copy of the file to download, so send the relevant headers and dump out the data
965 header("Content-Type: text/x-delimtext; name=\"config.$phpEx\"");
966 header("Content-disposition: attachment; filename=config.$phpEx");
967 echo $config_data;
968 exit;
971 // The option to download the config file is always available, so output it here
972 $template->assign_vars(array(
973 'BODY' => $lang['CONFIG_FILE_UNABLE_WRITE'],
974 'L_DL_CONFIG' => $lang['DL_CONFIG'],
975 'L_DL_CONFIG_EXPLAIN' => $lang['DL_CONFIG_EXPLAIN'],
976 'L_DL_DONE' => $lang['DONE'],
977 'L_DL_DOWNLOAD' => $lang['DL_DOWNLOAD'],
978 'S_HIDDEN' => $s_hidden_fields,
979 'S_SHOW_DOWNLOAD' => true,
980 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&amp;sub=config_file",
982 return;
984 else
986 $template->assign_vars(array(
987 'BODY' => $lang['CONFIG_FILE_WRITTEN'],
988 'L_SUBMIT' => $lang['NEXT_STEP'],
989 'S_HIDDEN' => $s_hidden_fields,
990 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&amp;sub=advanced",
992 return;
997 * Provide an opportunity to customise some advanced settings during the install
998 * in case it is necessary for them to be set to access later
1000 function obtain_advanced_settings($mode, $sub)
1002 global $lang, $template, $phpEx;
1004 $this->page_title = $lang['STAGE_ADVANCED'];
1006 // Obtain any submitted data
1007 $data = $this->get_submitted_data();
1009 if ($data['dbms'] == '')
1011 // Someone's been silly and tried calling this page direct
1012 // So we send them back to the start to do it again properly
1013 $this->p_master->redirect("index.$phpEx?mode=install");
1016 $s_hidden_fields = ($data['img_imagick']) ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
1017 $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
1019 // HTTP_HOST is having the correct browser url in most cases...
1020 $server_name = (!empty($_SERVER['HTTP_HOST'])) ? strtolower($_SERVER['HTTP_HOST']) : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'));
1022 // HTTP HOST can carry a port number...
1023 if (strpos($server_name, ':') !== false)
1025 $server_name = substr($server_name, 0, strpos($server_name, ':'));
1028 $data['email_enable'] = ($data['email_enable'] !== '') ? $data['email_enable'] : true;
1029 $data['server_name'] = ($data['server_name'] !== '') ? $data['server_name'] : $server_name;
1030 $data['server_port'] = ($data['server_port'] !== '') ? $data['server_port'] : ((!empty($_SERVER['SERVER_PORT'])) ? (int) $_SERVER['SERVER_PORT'] : (int) getenv('SERVER_PORT'));
1031 $data['server_protocol'] = ($data['server_protocol'] !== '') ? $data['server_protocol'] : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://');
1032 $data['cookie_secure'] = ($data['cookie_secure'] !== '') ? $data['cookie_secure'] : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? true : false);
1034 if ($data['script_path'] === '')
1036 $name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF');
1037 if (!$name)
1039 $name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI');
1042 // Replace backslashes and doubled slashes (could happen on some proxy setups)
1043 $name = str_replace(array('\\', '//', '/install'), '/', $name);
1044 $data['script_path'] = trim(dirname($name));
1047 foreach ($this->advanced_config_options as $config_key => $vars)
1049 if (!is_array($vars) && strpos($config_key, 'legend') === false)
1051 continue;
1054 if (strpos($config_key, 'legend') !== false)
1056 $template->assign_block_vars('options', array(
1057 'S_LEGEND' => true,
1058 'LEGEND' => $lang[$vars])
1061 continue;
1064 $options = isset($vars['options']) ? $vars['options'] : '';
1066 $template->assign_block_vars('options', array(
1067 'KEY' => $config_key,
1068 'TITLE' => $lang[$vars['lang']],
1069 'S_EXPLAIN' => $vars['explain'],
1070 'S_LEGEND' => false,
1071 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '',
1072 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options),
1077 $config_options = array_merge($this->db_config_options, $this->admin_config_options);
1078 foreach ($config_options as $config_key => $vars)
1080 if (!is_array($vars))
1082 continue;
1084 $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
1087 $submit = $lang['NEXT_STEP'];
1089 $url = $this->p_master->module_url . "?mode=$mode&amp;sub=create_table";
1091 $template->assign_vars(array(
1092 'BODY' => $lang['STAGE_ADVANCED_EXPLAIN'],
1093 'L_SUBMIT' => $submit,
1094 'S_HIDDEN' => $s_hidden_fields,
1095 'U_ACTION' => $url,
1100 * Load the contents of the schema into the database and then alter it based on what has been input during the installation
1102 function load_schema($mode, $sub)
1104 global $db, $lang, $template, $phpbb_root_path, $phpEx;
1106 $this->page_title = $lang['STAGE_CREATE_TABLE'];
1107 $s_hidden_fields = '';
1109 // Obtain any submitted data
1110 $data = $this->get_submitted_data();
1112 if ($data['dbms'] == '')
1114 // Someone's been silly and tried calling this page direct
1115 // So we send them back to the start to do it again properly
1116 $this->p_master->redirect("index.$phpEx?mode=install");
1119 // HTTP_HOST is having the correct browser url in most cases...
1120 $server_name = (!empty($_SERVER['HTTP_HOST'])) ? strtolower($_SERVER['HTTP_HOST']) : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'));
1121 $referer = (!empty($_SERVER['HTTP_REFERER'])) ? strtolower($_SERVER['HTTP_REFERER']) : getenv('HTTP_REFERER');
1123 // HTTP HOST can carry a port number...
1124 if (strpos($server_name, ':') !== false)
1126 $server_name = substr($server_name, 0, strpos($server_name, ':'));
1129 $cookie_domain = ($data['server_name'] != '') ? $data['server_name'] : $server_name;
1131 // Try to come up with the best solution for cookie domain...
1132 if (strpos($cookie_domain, 'www.') === 0)
1134 $cookie_domain = str_replace('www.', '.', $cookie_domain);
1137 // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
1138 $available_dbms = get_available_dbms($data['dbms']);
1140 if (!isset($available_dbms[$data['dbms']]))
1142 // Someone's been silly and tried providing a non-existant dbms
1143 $this->p_master->redirect("index.$phpEx?mode=install");
1146 $dbms = $available_dbms[$data['dbms']]['DRIVER'];
1148 // Load the appropriate database class if not already loaded
1149 include($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
1151 // Instantiate the database
1152 $db = new $sql_db();
1153 $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
1155 // NOTE: trigger_error does not work here.
1156 $db->sql_return_on_error(true);
1158 // If mysql is chosen, we need to adjust the schema filename slightly to reflect the correct version. ;)
1159 if ($data['dbms'] == 'mysql')
1161 if (version_compare($db->sql_server_info(true), '4.1.3', '>='))
1163 $available_dbms[$data['dbms']]['SCHEMA'] .= '_41';
1165 else
1167 $available_dbms[$data['dbms']]['SCHEMA'] .= '_40';
1171 // Ok we have the db info go ahead and read in the relevant schema
1172 // and work on building the table
1173 $dbms_schema = 'schemas/' . $available_dbms[$data['dbms']]['SCHEMA'] . '_schema.sql';
1175 // How should we treat this schema?
1176 $remove_remarks = $available_dbms[$data['dbms']]['COMMENTS'];
1177 $delimiter = $available_dbms[$data['dbms']]['DELIM'];
1179 $sql_query = @file_get_contents($dbms_schema);
1181 $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query);
1183 $remove_remarks($sql_query);
1185 $sql_query = split_sql_file($sql_query, $delimiter);
1187 foreach ($sql_query as $sql)
1189 //$sql = trim(str_replace('|', ';', $sql));
1190 if (!$db->sql_query($sql))
1192 $error = $db->sql_error();
1193 $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1196 unset($sql_query);
1198 // Ok tables have been built, let's fill in the basic information
1199 $sql_query = file_get_contents('schemas/schema_data.sql');
1201 // Deal with any special comments
1202 switch ($data['dbms'])
1204 case 'mssql':
1205 case 'mssql_odbc':
1206 $sql_query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $sql_query);
1207 break;
1209 case 'postgres':
1210 $sql_query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $sql_query);
1211 break;
1214 // Change prefix
1215 $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query);
1217 // Change language strings...
1218 $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query);
1220 // Since there is only one schema file we know the comment style and are able to remove it directly with remove_remarks
1221 remove_remarks($sql_query);
1222 $sql_query = split_sql_file($sql_query, ';');
1224 foreach ($sql_query as $sql)
1226 //$sql = trim(str_replace('|', ';', $sql));
1227 if (!$db->sql_query($sql))
1229 $error = $db->sql_error();
1230 $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1233 unset($sql_query);
1235 $current_time = time();
1237 $user_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
1239 if ($data['script_path'] !== '/')
1241 // Adjust destination path (no trailing slash)
1242 if (substr($data['script_path'], -1) == '/')
1244 $data['script_path'] = substr($data['script_path'], 0, -1);
1247 $data['script_path'] = str_replace(array('../', './'), '', $data['script_path']);
1249 if ($data['script_path'][0] != '/')
1251 $data['script_path'] = '/' . $data['script_path'];
1255 // Set default config and post data, this applies to all DB's
1256 $sql_ary = array(
1257 'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
1258 VALUES ('board_startdate', '$current_time')",
1260 'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value)
1261 VALUES ('default_lang', '" . $db->sql_escape($data['default_lang']) . "')",
1263 'UPDATE ' . $data['table_prefix'] . "config
1264 SET config_value = '" . $db->sql_escape($data['img_imagick']) . "'
1265 WHERE config_name = 'img_imagick'",
1267 'UPDATE ' . $data['table_prefix'] . "config
1268 SET config_value = '" . $db->sql_escape($data['server_name']) . "'
1269 WHERE config_name = 'server_name'",
1271 'UPDATE ' . $data['table_prefix'] . "config
1272 SET config_value = '" . $db->sql_escape($data['server_port']) . "'
1273 WHERE config_name = 'server_port'",
1275 'UPDATE ' . $data['table_prefix'] . "config
1276 SET config_value = '" . $db->sql_escape($data['board_email1']) . "'
1277 WHERE config_name = 'board_email'",
1279 'UPDATE ' . $data['table_prefix'] . "config
1280 SET config_value = '" . $db->sql_escape($data['board_email1']) . "'
1281 WHERE config_name = 'board_contact'",
1283 'UPDATE ' . $data['table_prefix'] . "config
1284 SET config_value = '" . $db->sql_escape($cookie_domain) . "'
1285 WHERE config_name = 'cookie_domain'",
1287 'UPDATE ' . $data['table_prefix'] . "config
1288 SET config_value = '" . $db->sql_escape($lang['default_dateformat']) . "'
1289 WHERE config_name = 'default_dateformat'",
1291 'UPDATE ' . $data['table_prefix'] . "config
1292 SET config_value = '" . $db->sql_escape($data['email_enable']) . "'
1293 WHERE config_name = 'email_enable'",
1295 'UPDATE ' . $data['table_prefix'] . "config
1296 SET config_value = '" . $db->sql_escape($data['smtp_delivery']) . "'
1297 WHERE config_name = 'smtp_delivery'",
1299 'UPDATE ' . $data['table_prefix'] . "config
1300 SET config_value = '" . $db->sql_escape($data['smtp_host']) . "'
1301 WHERE config_name = 'smtp_host'",
1303 'UPDATE ' . $data['table_prefix'] . "config
1304 SET config_value = '" . $db->sql_escape($data['smtp_auth']) . "'
1305 WHERE config_name = 'smtp_auth_method'",
1307 'UPDATE ' . $data['table_prefix'] . "config
1308 SET config_value = '" . $db->sql_escape($data['smtp_user']) . "'
1309 WHERE config_name = 'smtp_username'",
1311 'UPDATE ' . $data['table_prefix'] . "config
1312 SET config_value = '" . $db->sql_escape($data['smtp_pass']) . "'
1313 WHERE config_name = 'smtp_password'",
1315 'UPDATE ' . $data['table_prefix'] . "config
1316 SET config_value = '" . $db->sql_escape($data['cookie_secure']) . "'
1317 WHERE config_name = 'cookie_secure'",
1319 'UPDATE ' . $data['table_prefix'] . "config
1320 SET config_value = '" . $db->sql_escape($data['force_server_vars']) . "'
1321 WHERE config_name = 'force_server_vars'",
1323 'UPDATE ' . $data['table_prefix'] . "config
1324 SET config_value = '" . $db->sql_escape($data['script_path']) . "'
1325 WHERE config_name = 'script_path'",
1327 'UPDATE ' . $data['table_prefix'] . "config
1328 SET config_value = '" . $db->sql_escape($data['server_protocol']) . "'
1329 WHERE config_name = 'server_protocol'",
1331 'UPDATE ' . $data['table_prefix'] . "config
1332 SET config_value = '" . $db->sql_escape($data['admin_name']) . "'
1333 WHERE config_name = 'newest_username'",
1335 'UPDATE ' . $data['table_prefix'] . "config
1336 SET config_value = '" . md5(mt_rand()) . "'
1337 WHERE config_name = 'avatar_salt'",
1339 'UPDATE ' . $data['table_prefix'] . "users
1340 SET username = '" . $db->sql_escape($data['admin_name']) . "', user_password='" . $db->sql_escape(md5($data['admin_pass1'])) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($data['default_lang']) . "', user_email='" . $db->sql_escape($data['board_email1']) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . $db->sql_escape(phpbb_email_hash($data['board_email1'])) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($data['admin_name'])) . "'
1341 WHERE username = 'Admin'",
1343 'UPDATE ' . $data['table_prefix'] . "moderator_cache
1344 SET username = '" . $db->sql_escape($data['admin_name']) . "'
1345 WHERE username = 'Admin'",
1347 'UPDATE ' . $data['table_prefix'] . "forums
1348 SET forum_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
1349 WHERE forum_last_poster_name = 'Admin'",
1351 'UPDATE ' . $data['table_prefix'] . "topics
1352 SET topic_first_poster_name = '" . $db->sql_escape($data['admin_name']) . "', topic_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "'
1353 WHERE topic_first_poster_name = 'Admin'
1354 OR topic_last_poster_name = 'Admin'",
1356 'UPDATE ' . $data['table_prefix'] . "users
1357 SET user_regdate = $current_time",
1359 'UPDATE ' . $data['table_prefix'] . "posts
1360 SET post_time = $current_time, poster_ip = '" . $db->sql_escape($user_ip) . "'",
1362 'UPDATE ' . $data['table_prefix'] . "topics
1363 SET topic_time = $current_time, topic_last_post_time = $current_time",
1365 'UPDATE ' . $data['table_prefix'] . "forums
1366 SET forum_last_post_time = $current_time",
1368 'UPDATE ' . $data['table_prefix'] . "config
1369 SET config_value = '" . $db->sql_escape($db->sql_server_info(true)) . "'
1370 WHERE config_name = 'dbms_version'",
1373 if (@extension_loaded('gd') || can_load_dll('gd'))
1375 $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1376 SET config_value = 'phpbb_captcha_gd'
1377 WHERE config_name = 'captcha_plugin'";
1379 $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1380 SET config_value = '1'
1381 WHERE config_name = 'captcha_gd'";
1384 $ref = substr($referer, strpos($referer, '://') + 3);
1386 if (!(stripos($ref, $server_name) === 0))
1388 $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1389 SET config_value = '0'
1390 WHERE config_name = 'referer_validation'";
1393 // We set a (semi-)unique cookie name to bypass login issues related to the cookie name.
1394 $cookie_name = 'phpbb3_';
1395 $rand_str = md5(mt_rand());
1396 $rand_str = str_replace('0', 'z', base_convert($rand_str, 16, 35));
1397 $rand_str = substr($rand_str, 0, 5);
1398 $cookie_name .= strtolower($rand_str);
1400 $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
1401 SET config_value = '" . $db->sql_escape($cookie_name) . "'
1402 WHERE config_name = 'cookie_name'";
1404 foreach ($sql_ary as $sql)
1406 //$sql = trim(str_replace('|', ';', $sql));
1408 if (!$db->sql_query($sql))
1410 $error = $db->sql_error();
1411 $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__);
1415 $submit = $lang['NEXT_STEP'];
1417 $url = $this->p_master->module_url . "?mode=$mode&amp;sub=final";
1419 $template->assign_vars(array(
1420 'BODY' => $lang['STAGE_CREATE_TABLE_EXPLAIN'],
1421 'L_SUBMIT' => $submit,
1422 'S_HIDDEN' => build_hidden_fields($data),
1423 'U_ACTION' => $url,
1428 * Build the search index...
1430 function build_search_index($mode, $sub)
1432 global $db, $lang, $phpbb_root_path, $phpEx, $config;
1434 // Obtain any submitted data
1435 $data = $this->get_submitted_data();
1436 $table_prefix = $data['table_prefix'];
1438 // If we get here and the extension isn't loaded it should be safe to just go ahead and load it
1439 $available_dbms = get_available_dbms($data['dbms']);
1441 if (!isset($available_dbms[$data['dbms']]))
1443 // Someone's been silly and tried providing a non-existant dbms
1444 $this->p_master->redirect("index.$phpEx?mode=install");
1447 $dbms = $available_dbms[$data['dbms']]['DRIVER'];
1449 // Load the appropriate database class if not already loaded
1450 include($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
1452 // Instantiate the database
1453 $db = new $sql_db();
1454 $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false);
1456 // NOTE: trigger_error does not work here.
1457 $db->sql_return_on_error(true);
1459 include_once($phpbb_root_path . 'includes/constants.' . $phpEx);
1460 include_once($phpbb_root_path . 'includes/search/fulltext_native.' . $phpEx);
1462 // Fill the config array - it is needed by those functions we call
1463 $sql = 'SELECT *
1464 FROM ' . CONFIG_TABLE;
1465 $result = $db->sql_query($sql);
1467 $config = array();
1468 while ($row = $db->sql_fetchrow($result))
1470 $config[$row['config_name']] = $row['config_value'];
1472 $db->sql_freeresult($result);
1474 $error = false;
1475 $search = new fulltext_native($error);
1477 $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
1478 FROM ' . POSTS_TABLE;
1479 $result = $db->sql_query($sql);
1481 while ($row = $db->sql_fetchrow($result))
1483 $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
1485 $db->sql_freeresult($result);
1489 * Populate the module tables
1491 function add_modules($mode, $sub)
1493 global $db, $lang, $phpbb_root_path, $phpEx;
1495 include_once($phpbb_root_path . 'includes/acp/acp_modules.' . $phpEx);
1497 $_module = new acp_modules();
1498 $module_classes = array('acp', 'mcp', 'ucp');
1500 // Add categories
1501 foreach ($module_classes as $module_class)
1503 $categories = array();
1505 // Set the module class
1506 $_module->module_class = $module_class;
1508 foreach ($this->module_categories[$module_class] as $cat_name => $subs)
1510 $module_data = array(
1511 'module_basename' => '',
1512 'module_enabled' => 1,
1513 'module_display' => 1,
1514 'parent_id' => 0,
1515 'module_class' => $module_class,
1516 'module_langname' => $cat_name,
1517 'module_mode' => '',
1518 'module_auth' => '',
1521 // Add category
1522 $_module->update_module_data($module_data, true);
1524 // Check for last sql error happened
1525 if ($db->sql_error_triggered)
1527 $error = $db->sql_error($db->sql_error_sql);
1528 $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__);
1531 $categories[$cat_name]['id'] = (int) $module_data['module_id'];
1532 $categories[$cat_name]['parent_id'] = 0;
1534 // Create sub-categories...
1535 if (is_array($subs))
1537 foreach ($subs as $level2_name)
1539 $module_data = array(
1540 'module_basename' => '',
1541 'module_enabled' => 1,
1542 'module_display' => 1,
1543 'parent_id' => (int) $categories[$cat_name]['id'],
1544 'module_class' => $module_class,
1545 'module_langname' => $level2_name,
1546 'module_mode' => '',
1547 'module_auth' => '',
1550 $_module->update_module_data($module_data, true);
1552 // Check for last sql error happened
1553 if ($db->sql_error_triggered)
1555 $error = $db->sql_error($db->sql_error_sql);
1556 $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__);
1559 $categories[$level2_name]['id'] = (int) $module_data['module_id'];
1560 $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id'];
1565 // Get the modules we want to add... returned sorted by name
1566 $module_info = $_module->get_module_infos('', $module_class);
1568 foreach ($module_info as $module_basename => $fileinfo)
1570 foreach ($fileinfo['modes'] as $module_mode => $row)
1572 foreach ($row['cat'] as $cat_name)
1574 if (!isset($categories[$cat_name]))
1576 continue;
1579 $module_data = array(
1580 'module_basename' => $module_basename,
1581 'module_enabled' => 1,
1582 'module_display' => (isset($row['display'])) ? (int) $row['display'] : 1,
1583 'parent_id' => (int) $categories[$cat_name]['id'],
1584 'module_class' => $module_class,
1585 'module_langname' => $row['title'],
1586 'module_mode' => $module_mode,
1587 'module_auth' => $row['auth'],
1590 $_module->update_module_data($module_data, true);
1592 // Check for last sql error happened
1593 if ($db->sql_error_triggered)
1595 $error = $db->sql_error($db->sql_error_sql);
1596 $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__);
1602 // Move some of the modules around since the code above will put them in the wrong place
1603 if ($module_class == 'acp')
1605 // Move main module 4 up...
1606 $sql = 'SELECT *
1607 FROM ' . MODULES_TABLE . "
1608 WHERE module_basename = 'main'
1609 AND module_class = 'acp'
1610 AND module_mode = 'main'";
1611 $result = $db->sql_query($sql);
1612 $row = $db->sql_fetchrow($result);
1613 $db->sql_freeresult($result);
1615 $_module->move_module_by($row, 'move_up', 4);
1617 // Move permissions intro screen module 4 up...
1618 $sql = 'SELECT *
1619 FROM ' . MODULES_TABLE . "
1620 WHERE module_basename = 'permissions'
1621 AND module_class = 'acp'
1622 AND module_mode = 'intro'";
1623 $result = $db->sql_query($sql);
1624 $row = $db->sql_fetchrow($result);
1625 $db->sql_freeresult($result);
1627 $_module->move_module_by($row, 'move_up', 4);
1629 // Move manage users screen module 5 up...
1630 $sql = 'SELECT *
1631 FROM ' . MODULES_TABLE . "
1632 WHERE module_basename = 'users'
1633 AND module_class = 'acp'
1634 AND module_mode = 'overview'";
1635 $result = $db->sql_query($sql);
1636 $row = $db->sql_fetchrow($result);
1637 $db->sql_freeresult($result);
1639 $_module->move_module_by($row, 'move_up', 5);
1642 if ($module_class == 'ucp')
1644 // Move attachment module 4 down...
1645 $sql = 'SELECT *
1646 FROM ' . MODULES_TABLE . "
1647 WHERE module_basename = 'attachments'
1648 AND module_class = 'ucp'
1649 AND module_mode = 'attachments'";
1650 $result = $db->sql_query($sql);
1651 $row = $db->sql_fetchrow($result);
1652 $db->sql_freeresult($result);
1654 $_module->move_module_by($row, 'move_down', 4);
1657 // And now for the special ones
1658 // (these are modules which appear in multiple categories and thus get added manually to some for more control)
1659 if (isset($this->module_extras[$module_class]))
1661 foreach ($this->module_extras[$module_class] as $cat_name => $mods)
1663 $sql = 'SELECT module_id, left_id, right_id
1664 FROM ' . MODULES_TABLE . "
1665 WHERE module_langname = '" . $db->sql_escape($cat_name) . "'
1666 AND module_class = '" . $db->sql_escape($module_class) . "'";
1667 $result = $db->sql_query_limit($sql, 1);
1668 $row2 = $db->sql_fetchrow($result);
1669 $db->sql_freeresult($result);
1671 foreach ($mods as $mod_name)
1673 $sql = 'SELECT *
1674 FROM ' . MODULES_TABLE . "
1675 WHERE module_langname = '" . $db->sql_escape($mod_name) . "'
1676 AND module_class = '" . $db->sql_escape($module_class) . "'
1677 AND module_basename <> ''";
1678 $result = $db->sql_query_limit($sql, 1);
1679 $row = $db->sql_fetchrow($result);
1680 $db->sql_freeresult($result);
1682 $module_data = array(
1683 'module_basename' => $row['module_basename'],
1684 'module_enabled' => (int) $row['module_enabled'],
1685 'module_display' => (int) $row['module_display'],
1686 'parent_id' => (int) $row2['module_id'],
1687 'module_class' => $row['module_class'],
1688 'module_langname' => $row['module_langname'],
1689 'module_mode' => $row['module_mode'],
1690 'module_auth' => $row['module_auth'],
1693 $_module->update_module_data($module_data, true);
1695 // Check for last sql error happened
1696 if ($db->sql_error_triggered)
1698 $error = $db->sql_error($db->sql_error_sql);
1699 $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__);
1705 $_module->remove_cache_file();
1710 * Populate the language tables
1712 function add_language($mode, $sub)
1714 global $db, $lang, $phpbb_root_path, $phpEx;
1716 $dir = @opendir($phpbb_root_path . 'language');
1718 if (!$dir)
1720 $this->error('Unable to access the language directory', __LINE__, __FILE__);
1723 while (($file = readdir($dir)) !== false)
1725 $path = $phpbb_root_path . 'language/' . $file;
1727 if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS')
1729 continue;
1732 if (is_dir($path) && file_exists($path . '/iso.txt'))
1734 $lang_file = file("$path/iso.txt");
1736 $lang_pack = array(
1737 'lang_iso' => basename($path),
1738 'lang_dir' => basename($path),
1739 'lang_english_name' => trim(htmlspecialchars($lang_file[0])),
1740 'lang_local_name' => trim(htmlspecialchars($lang_file[1], ENT_COMPAT, 'UTF-8')),
1741 'lang_author' => trim(htmlspecialchars($lang_file[2], ENT_COMPAT, 'UTF-8')),
1744 $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $lang_pack));
1746 if ($db->sql_error_triggered)
1748 $error = $db->sql_error($db->sql_error_sql);
1749 $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__);
1752 $valid_localized = array(
1753 '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',
1756 $sql_ary = array();
1758 $sql = 'SELECT *
1759 FROM ' . STYLES_IMAGESET_TABLE;
1760 $result = $db->sql_query($sql);
1762 while ($imageset_row = $db->sql_fetchrow($result))
1764 if (@file_exists("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['lang_iso']}/imageset.cfg"))
1766 $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$imageset_row['imageset_path']}/imageset/{$lang_pack['lang_iso']}/imageset.cfg");
1767 foreach ($cfg_data_imageset_data as $image_name => $value)
1769 if (strpos($value, '*') !== false)
1771 if (substr($value, -1, 1) === '*')
1773 list($image_filename, $image_height) = explode('*', $value);
1774 $image_width = 0;
1776 else
1778 list($image_filename, $image_height, $image_width) = explode('*', $value);
1781 else
1783 $image_filename = $value;
1784 $image_height = $image_width = 0;
1787 if (strpos($image_name, 'img_') === 0 && $image_filename)
1789 $image_name = substr($image_name, 4);
1790 if (in_array($image_name, $valid_localized))
1792 $sql_ary[] = array(
1793 'image_name' => (string) $image_name,
1794 'image_filename' => (string) $image_filename,
1795 'image_height' => (int) $image_height,
1796 'image_width' => (int) $image_width,
1797 'imageset_id' => (int) $imageset_row['imageset_id'],
1798 'image_lang' => (string) $lang_pack['lang_iso'],
1805 $db->sql_freeresult($result);
1807 if (sizeof($sql_ary))
1809 $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
1811 if ($db->sql_error_triggered)
1813 $error = $db->sql_error($db->sql_error_sql);
1814 $this->p_master->db_error($error['message'], $db->sql_error_sql, __LINE__, __FILE__);
1819 closedir($dir);
1823 * Add search robots to the database
1825 function add_bots($mode, $sub)
1827 global $db, $lang, $phpbb_root_path, $phpEx, $config;
1829 // Obtain any submitted data
1830 $data = $this->get_submitted_data();
1832 // Fill the config array - it is needed by those functions we call
1833 $sql = 'SELECT *
1834 FROM ' . CONFIG_TABLE;
1835 $result = $db->sql_query($sql);
1837 $config = array();
1838 while ($row = $db->sql_fetchrow($result))
1840 $config[$row['config_name']] = $row['config_value'];
1842 $db->sql_freeresult($result);
1844 $sql = 'SELECT group_id
1845 FROM ' . GROUPS_TABLE . "
1846 WHERE group_name = 'BOTS'";
1847 $result = $db->sql_query($sql);
1848 $group_id = (int) $db->sql_fetchfield('group_id');
1849 $db->sql_freeresult($result);
1851 if (!$group_id)
1853 // If we reach this point then something has gone very wrong
1854 $this->p_master->error($lang['NO_GROUP'], __LINE__, __FILE__);
1857 if (!function_exists('user_add'))
1859 include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
1862 foreach ($this->bot_list as $bot_name => $bot_ary)
1864 $user_row = array(
1865 'user_type' => USER_IGNORE,
1866 'group_id' => $group_id,
1867 'username' => $bot_name,
1868 'user_regdate' => time(),
1869 'user_password' => '',
1870 'user_colour' => '9E8DA7',
1871 'user_email' => '',
1872 'user_lang' => $data['default_lang'],
1873 'user_style' => 1,
1874 'user_timezone' => 0,
1875 'user_dateformat' => $lang['default_dateformat'],
1876 'user_allow_massemail' => 0,
1879 $user_id = user_add($user_row);
1881 if (!$user_id)
1883 // If we can't insert this user then continue to the next one to avoid inconsistant data
1884 $this->p_master->db_error('Unable to insert bot into users table', $db->sql_error_sql, __LINE__, __FILE__, true);
1885 continue;
1888 $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
1889 'bot_active' => 1,
1890 'bot_name' => (string) $bot_name,
1891 'user_id' => (int) $user_id,
1892 'bot_agent' => (string) $bot_ary[0],
1893 'bot_ip' => (string) $bot_ary[1],
1896 $result = $db->sql_query($sql);
1901 * Sends an email to the board administrator with their password and some useful links
1903 function email_admin($mode, $sub)
1905 global $auth, $config, $db, $lang, $template, $user, $phpbb_root_path, $phpEx;
1907 $this->page_title = $lang['STAGE_FINAL'];
1909 // Obtain any submitted data
1910 $data = $this->get_submitted_data();
1912 $sql = 'SELECT *
1913 FROM ' . CONFIG_TABLE;
1914 $result = $db->sql_query($sql);
1916 $config = array();
1917 while ($row = $db->sql_fetchrow($result))
1919 $config[$row['config_name']] = $row['config_value'];
1921 $db->sql_freeresult($result);
1923 $user->session_begin();
1924 $auth->login($data['admin_name'], $data['admin_pass1'], false, true, true);
1926 // OK, Now that we've reached this point we can be confident that everything
1927 // is installed and working......I hope :)
1928 // So it's time to send an email to the administrator confirming the details
1929 // they entered
1931 if ($config['email_enable'])
1933 include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
1935 $messenger = new messenger(false);
1937 $messenger->template('installed', $data['language']);
1939 $messenger->to($data['board_email1'], $data['admin_name']);
1941 $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']);
1942 $messenger->headers('X-AntiAbuse: User_id - ' . $user->data['user_id']);
1943 $messenger->headers('X-AntiAbuse: Username - ' . $user->data['username']);
1944 $messenger->headers('X-AntiAbuse: User IP - ' . $user->ip);
1946 $messenger->assign_vars(array(
1947 'USERNAME' => htmlspecialchars_decode($data['admin_name']),
1948 'PASSWORD' => htmlspecialchars_decode($data['admin_pass1']))
1951 $messenger->send(NOTIFY_EMAIL);
1954 // And finally, add a note to the log
1955 add_log('admin', 'LOG_INSTALL_INSTALLED', $config['version']);
1957 $template->assign_vars(array(
1958 'TITLE' => $lang['INSTALL_CONGRATS'],
1959 'BODY' => sprintf($lang['INSTALL_CONGRATS_EXPLAIN'], $config['version'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=convert&amp;language=' . $data['language']), '../docs/README.html'),
1960 'L_SUBMIT' => $lang['INSTALL_LOGIN'],
1961 'U_ACTION' => append_sid($phpbb_root_path . 'adm/index.' . $phpEx, 'i=send_statistics&amp;mode=send_statistics'),
1966 * Generate a list of available mail server authentication methods
1968 function mail_auth_select($selected_method)
1970 global $lang;
1972 $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP');
1973 $s_smtp_auth_options = '';
1975 foreach ($auth_methods as $method)
1977 $s_smtp_auth_options .= '<option value="' . $method . '"' . (($selected_method == $method) ? ' selected="selected"' : '') . '>' . $lang['SMTP_' . str_replace('-', '_', $method)] . '</option>';
1980 return $s_smtp_auth_options;
1984 * Get submitted data
1986 function get_submitted_data()
1988 return array(
1989 'language' => basename(request_var('language', '')),
1990 'dbms' => request_var('dbms', ''),
1991 'dbhost' => request_var('dbhost', ''),
1992 'dbport' => request_var('dbport', ''),
1993 'dbuser' => request_var('dbuser', ''),
1994 'dbpasswd' => request_var('dbpasswd', '', true),
1995 'dbname' => request_var('dbname', ''),
1996 'table_prefix' => request_var('table_prefix', ''),
1997 'default_lang' => basename(request_var('default_lang', '')),
1998 'admin_name' => utf8_normalize_nfc(request_var('admin_name', '', true)),
1999 'admin_pass1' => request_var('admin_pass1', '', true),
2000 'admin_pass2' => request_var('admin_pass2', '', true),
2001 'board_email1' => strtolower(request_var('board_email1', '')),
2002 'board_email2' => strtolower(request_var('board_email2', '')),
2003 'img_imagick' => request_var('img_imagick', ''),
2004 'ftp_path' => request_var('ftp_path', ''),
2005 'ftp_user' => request_var('ftp_user', ''),
2006 'ftp_pass' => request_var('ftp_pass', ''),
2007 'email_enable' => request_var('email_enable', ''),
2008 'smtp_delivery' => request_var('smtp_delivery', ''),
2009 'smtp_host' => request_var('smtp_host', ''),
2010 'smtp_auth' => request_var('smtp_auth', ''),
2011 'smtp_user' => request_var('smtp_user', ''),
2012 'smtp_pass' => request_var('smtp_pass', ''),
2013 'cookie_secure' => request_var('cookie_secure', ''),
2014 'force_server_vars' => request_var('force_server_vars', ''),
2015 'server_protocol' => request_var('server_protocol', ''),
2016 'server_name' => request_var('server_name', ''),
2017 'server_port' => request_var('server_port', ''),
2018 'script_path' => request_var('script_path', ''),
2023 * The information below will be used to build the input fields presented to the user
2025 var $db_config_options = array(
2026 'legend1' => 'DB_CONFIG',
2027 'dbms' => array('lang' => 'DBMS', 'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\')', 'explain' => false),
2028 'dbhost' => array('lang' => 'DB_HOST', 'type' => 'text:25:100', 'explain' => true),
2029 'dbport' => array('lang' => 'DB_PORT', 'type' => 'text:25:100', 'explain' => true),
2030 'dbname' => array('lang' => 'DB_NAME', 'type' => 'text:25:100', 'explain' => false),
2031 'dbuser' => array('lang' => 'DB_USERNAME', 'type' => 'text:25:100', 'explain' => false),
2032 'dbpasswd' => array('lang' => 'DB_PASSWORD', 'type' => 'password:25:100', 'explain' => false),
2033 'table_prefix' => array('lang' => 'TABLE_PREFIX', 'type' => 'text:25:100', 'explain' => false),
2035 var $admin_config_options = array(
2036 'legend1' => 'ADMIN_CONFIG',
2037 'default_lang' => array('lang' => 'DEFAULT_LANG', 'type' => 'select', 'options' => '$this->module->inst_language_select(\'{VALUE}\')', 'explain' => false),
2038 'admin_name' => array('lang' => 'ADMIN_USERNAME', 'type' => 'text:25:100', 'explain' => true),
2039 'admin_pass1' => array('lang' => 'ADMIN_PASSWORD', 'type' => 'password:25:100', 'explain' => true),
2040 'admin_pass2' => array('lang' => 'ADMIN_PASSWORD_CONFIRM', 'type' => 'password:25:100', 'explain' => false),
2041 'board_email1' => array('lang' => 'CONTACT_EMAIL', 'type' => 'text:25:100', 'explain' => false),
2042 'board_email2' => array('lang' => 'CONTACT_EMAIL_CONFIRM', 'type' => 'text:25:100', 'explain' => false),
2044 var $advanced_config_options = array(
2045 'legend1' => 'ACP_EMAIL_SETTINGS',
2046 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'type' => 'radio:enabled_disabled', 'explain' => true),
2047 'smtp_delivery' => array('lang' => 'USE_SMTP', 'type' => 'radio:yes_no', 'explain' => true),
2048 'smtp_host' => array('lang' => 'SMTP_SERVER', 'type' => 'text:25:50', 'explain' => false),
2049 'smtp_auth' => array('lang' => 'SMTP_AUTH_METHOD', 'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true),
2050 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true),
2051 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true),
2053 'legend2' => 'SERVER_URL_SETTINGS',
2054 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'type' => 'radio:enabled_disabled', 'explain' => true),
2055 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'type' => 'radio:yes_no', 'explain' => true),
2056 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'type' => 'text:10:10', 'explain' => true),
2057 'server_name' => array('lang' => 'SERVER_NAME', 'type' => 'text:40:255', 'explain' => true),
2058 'server_port' => array('lang' => 'SERVER_PORT', 'type' => 'text:5:5', 'explain' => true),
2059 'script_path' => array('lang' => 'SCRIPT_PATH', 'type' => 'text::255', 'explain' => true),
2063 * Specific PHP modules we may require for certain optional or extended features
2065 var $php_dlls_other = array('zlib', 'ftp', 'gd', 'xml');
2068 * A list of the web-crawlers/bots we recognise by default
2070 * Candidates but not included:
2071 * 'Accoona [Bot]' 'Accoona-AI-Agent/'
2072 * 'ASPseek [Crawler]' 'ASPseek/'
2073 * 'Boitho [Crawler]' 'boitho.com-dc/'
2074 * 'Bunnybot [Bot]' 'powered by www.buncat.de'
2075 * 'Cosmix [Bot]' 'cfetch/'
2076 * 'Crawler Search [Crawler]' '.Crawler-Search.de'
2077 * 'Findexa [Crawler]' 'Findexa Crawler ('
2078 * 'GBSpider [Spider]' 'GBSpider v'
2079 * 'genie [Bot]' 'genieBot ('
2080 * 'Hogsearch [Bot]' 'oegp v. 1.3.0'
2081 * 'Insuranco [Bot]' 'InsurancoBot'
2082 * 'IRLbot [Bot]' 'http://irl.cs.tamu.edu/crawler'
2083 * 'ISC Systems [Bot]' 'ISC Systems iRc Search'
2084 * 'Jyxobot [Bot]' 'Jyxobot/'
2085 * 'Kraehe [Metasuche]' '-DIE-KRAEHE- META-SEARCH-ENGINE/'
2086 * 'LinkWalker' 'LinkWalker'
2087 * 'MMSBot [Bot]' 'http://www.mmsweb.at/bot.html'
2088 * 'Naver [Bot]' 'nhnbot@naver.com)'
2089 * 'NetResearchServer' 'NetResearchServer/'
2090 * 'Nimble [Crawler]' 'NimbleCrawler'
2091 * 'Ocelli [Bot]' 'Ocelli/'
2092 * 'Onsearch [Bot]' 'onCHECK-Robot'
2093 * 'Orange [Spider]' 'OrangeSpider'
2094 * 'Sproose [Bot]' 'http://www.sproose.com/bot'
2095 * 'Susie [Sync]' '!Susie (http://www.sync2it.com/susie)'
2096 * 'Tbot [Bot]' 'Tbot/'
2097 * 'Thumbshots [Capture]' 'thumbshots-de-Bot'
2098 * 'Vagabondo [Crawler]' 'http://webagent.wise-guys.nl/'
2099 * 'Walhello [Bot]' 'appie 1.1 (www.walhello.com)'
2100 * 'WissenOnline [Bot]' 'WissenOnline-Bot'
2101 * 'WWWeasel [Bot]' 'WWWeasel Robot v'
2102 * 'Xaldon [Spider]' 'Xaldon WebSpider'
2104 var $bot_list = array(
2105 'AdsBot [Google]' => array('AdsBot-Google', ''),
2106 'Alexa [Bot]' => array('ia_archiver', ''),
2107 'Alta Vista [Bot]' => array('Scooter/', ''),
2108 'Ask Jeeves [Bot]' => array('Ask Jeeves', ''),
2109 'Baidu [Spider]' => array('Baiduspider+(', ''),
2110 'Exabot [Bot]' => array('Exabot/', ''),
2111 'FAST Enterprise [Crawler]' => array('FAST Enterprise Crawler', ''),
2112 'FAST WebCrawler [Crawler]' => array('FAST-WebCrawler/', ''),
2113 'Francis [Bot]' => array('http://www.neomo.de/', ''),
2114 'Gigabot [Bot]' => array('Gigabot/', ''),
2115 'Google Adsense [Bot]' => array('Mediapartners-Google', ''),
2116 'Google Desktop' => array('Google Desktop', ''),
2117 'Google Feedfetcher' => array('Feedfetcher-Google', ''),
2118 'Google [Bot]' => array('Googlebot', ''),
2119 'Heise IT-Markt [Crawler]' => array('heise-IT-Markt-Crawler', ''),
2120 'Heritrix [Crawler]' => array('heritrix/1.', ''),
2121 'IBM Research [Bot]' => array('ibm.com/cs/crawler', ''),
2122 'ICCrawler - ICjobs' => array('ICCrawler - ICjobs', ''),
2123 'ichiro [Crawler]' => array('ichiro/', ''),
2124 'Majestic-12 [Bot]' => array('MJ12bot/', ''),
2125 'Metager [Bot]' => array('MetagerBot/', ''),
2126 'MSN NewsBlogs' => array('msnbot-NewsBlogs/', ''),
2127 'MSN [Bot]' => array('msnbot/', ''),
2128 'MSNbot Media' => array('msnbot-media/', ''),
2129 'NG-Search [Bot]' => array('NG-Search/', ''),
2130 'Nutch [Bot]' => array('http://lucene.apache.org/nutch/', ''),
2131 'Nutch/CVS [Bot]' => array('NutchCVS/', ''),
2132 'OmniExplorer [Bot]' => array('OmniExplorer_Bot/', ''),
2133 'Online link [Validator]' => array('online link validator', ''),
2134 'psbot [Picsearch]' => array('psbot/0', ''),
2135 'Seekport [Bot]' => array('Seekbot/', ''),
2136 'Sensis [Crawler]' => array('Sensis Web Crawler', ''),
2137 'SEO Crawler' => array('SEO search Crawler/', ''),
2138 'Seoma [Crawler]' => array('Seoma [SEO Crawler]', ''),
2139 'SEOSearch [Crawler]' => array('SEOsearch/', ''),
2140 'Snappy [Bot]' => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''),
2141 'Steeler [Crawler]' => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''),
2142 'Synoo [Bot]' => array('SynooBot/', ''),
2143 'Telekom [Bot]' => array('crawleradmin.t-info@telekom.de', ''),
2144 'TurnitinBot [Bot]' => array('TurnitinBot/', ''),
2145 'Voyager [Bot]' => array('voyager/1.0', ''),
2146 'W3 [Sitesearch]' => array('W3 SiteSearch Crawler', ''),
2147 'W3C [Linkcheck]' => array('W3C-checklink/', ''),
2148 'W3C [Validator]' => array('W3C_*Validator', ''),
2149 'WiseNut [Bot]' => array('http://www.WISEnutbot.com', ''),
2150 'YaCy [Bot]' => array('yacybot', ''),
2151 'Yahoo MMCrawler [Bot]' => array('Yahoo-MMCrawler/', ''),
2152 'Yahoo Slurp [Bot]' => array('Yahoo! DE Slurp', ''),
2153 'Yahoo [Bot]' => array('Yahoo! Slurp', ''),
2154 'YahooSeeker [Bot]' => array('YahooSeeker/', ''),
2158 * Define the module structure so that we can populate the database without
2159 * needing to hard-code module_id values
2161 var $module_categories = array(
2162 'acp' => array(
2163 'ACP_CAT_GENERAL' => array(
2164 'ACP_QUICK_ACCESS',
2165 'ACP_BOARD_CONFIGURATION',
2166 'ACP_CLIENT_COMMUNICATION',
2167 'ACP_SERVER_CONFIGURATION',
2169 'ACP_CAT_FORUMS' => array(
2170 'ACP_MANAGE_FORUMS',
2171 'ACP_FORUM_BASED_PERMISSIONS',
2173 'ACP_CAT_POSTING' => array(
2174 'ACP_MESSAGES',
2175 'ACP_ATTACHMENTS',
2177 'ACP_CAT_USERGROUP' => array(
2178 'ACP_CAT_USERS',
2179 'ACP_GROUPS',
2180 'ACP_USER_SECURITY',
2182 'ACP_CAT_PERMISSIONS' => array(
2183 'ACP_GLOBAL_PERMISSIONS',
2184 'ACP_FORUM_BASED_PERMISSIONS',
2185 'ACP_PERMISSION_ROLES',
2186 'ACP_PERMISSION_MASKS',
2188 'ACP_CAT_STYLES' => array(
2189 'ACP_STYLE_MANAGEMENT',
2190 'ACP_STYLE_COMPONENTS',
2192 'ACP_CAT_MAINTENANCE' => array(
2193 'ACP_FORUM_LOGS',
2194 'ACP_CAT_DATABASE',
2196 'ACP_CAT_SYSTEM' => array(
2197 'ACP_AUTOMATION',
2198 'ACP_GENERAL_TASKS',
2199 'ACP_MODULE_MANAGEMENT',
2201 'ACP_CAT_DOT_MODS' => null,
2203 'mcp' => array(
2204 'MCP_MAIN' => null,
2205 'MCP_QUEUE' => null,
2206 'MCP_REPORTS' => null,
2207 'MCP_NOTES' => null,
2208 'MCP_WARN' => null,
2209 'MCP_LOGS' => null,
2210 'MCP_BAN' => null,
2212 'ucp' => array(
2213 'UCP_MAIN' => null,
2214 'UCP_PROFILE' => null,
2215 'UCP_PREFS' => null,
2216 'UCP_PM' => null,
2217 'UCP_USERGROUPS' => null,
2218 'UCP_ZEBRA' => null,
2222 var $module_extras = array(
2223 'acp' => array(
2224 'ACP_QUICK_ACCESS' => array(
2225 'ACP_MANAGE_USERS',
2226 'ACP_GROUPS_MANAGE',
2227 'ACP_MANAGE_FORUMS',
2228 'ACP_MOD_LOGS',
2229 'ACP_BOTS',
2230 'ACP_PHP_INFO',
2232 'ACP_FORUM_BASED_PERMISSIONS' => array(
2233 'ACP_FORUM_PERMISSIONS',
2234 'ACP_FORUM_PERMISSIONS_COPY',
2235 'ACP_FORUM_MODERATORS',
2236 'ACP_USERS_FORUM_PERMISSIONS',
2237 'ACP_GROUPS_FORUM_PERMISSIONS',