1<?php
2/**
3 * MyBB 1.8
4 * Copyright 2014 MyBB Group, All Rights Reserved
5 *
6 * Website: http://www.mybb.com
7 * License: http://www.mybb.com/about/license
8 *
9 */
10
11@set_time_limit(0);
12
13define('MYBB_ROOT', dirname(dirname(__FILE__))."/");
14define("INSTALL_ROOT", dirname(__FILE__)."/");
15define("TIME_NOW", time());
16define("IN_MYBB", 1);
17define("IN_INSTALL", 1);
18
19if(function_exists('date_default_timezone_set') && !ini_get('date.timezone'))
20{
21	date_default_timezone_set('GMT');
22}
23
24require_once MYBB_ROOT.'inc/class_error.php';
25$error_handler = new errorHandler();
26
27require_once MYBB_ROOT.'inc/class_core.php';
28$mybb = new MyBB;
29
30// Include the files necessary for installation
31require_once MYBB_ROOT.'inc/class_timers.php';
32require_once MYBB_ROOT.'inc/functions.php';
33
34$admin_dir = "admin";
35
36// Perform a check if MyBB is already installed or not
37$installed = false;
38if(file_exists(MYBB_ROOT."/inc/config.php"))
39{
40	require MYBB_ROOT."/inc/config.php";
41	if(isset($config) && is_array($config))
42	{
43		$installed = true;
44		if(isset($config['admindir']))
45		{
46			$admin_dir = $config['admindir'];
47		}
48		else if(isset($config['admin_dir']))
49		{
50			$admin_dir = $config['admin_dir'];
51		}
52	}
53}
54
55require_once MYBB_ROOT.'inc/functions_user.php';
56require_once MYBB_ROOT.'inc/class_language.php';
57$lang = new MyLanguage();
58$lang->set_path(INSTALL_ROOT.'resources');
59$lang->load('language');
60
61// Load DB interface
62require_once MYBB_ROOT."inc/db_base.php";
63require_once MYBB_ROOT."inc/AbstractPdoDbDriver.php";
64
65// Prevent any shut down functions from running
66$done_shutdown = 1;
67
68// Include the necessary constants for installation
69$grouppermignore = array('gid', 'type', 'title', 'description', 'namestyle', 'usertitle', 'stars', 'starimage', 'image');
70$groupzerogreater = array('pmquota', 'maxpmrecipients', 'maxreputationsday', 'attachquota', 'maxemails', 'maxwarningsday', 'maxposts', 'edittimelimit', 'canusesigxposts', 'maxreputationsperuser', 'maxreputationsperthread', 'emailfloodtime');
71$displaygroupfields = array('title', 'description', 'namestyle', 'usertitle', 'stars', 'starimage', 'image');
72$fpermfields = array('canview', 'canviewthreads', 'candlattachments', 'canpostthreads', 'canpostreplys', 'canpostattachments', 'canratethreads', 'caneditposts', 'candeleteposts', 'candeletethreads', 'caneditattachments', 'canpostpolls', 'canvotepolls', 'cansearch', 'modposts', 'modthreads', 'modattachments', 'mod_edit_posts');
73
74// Include the installation resources
75require_once INSTALL_ROOT.'resources/output.php';
76$output = new installerOutput;
77
78$dboptions = array();
79
80if(function_exists('mysqli_connect'))
81{
82	$dboptions['mysqli'] = array(
83		'class' => 'DB_MySQLi',
84		'title' => 'MySQL Improved',
85		'short_title' => 'MySQLi',
86		'structure_file' => 'mysql_db_tables.php',
87		'population_file' => 'mysql_db_inserts.php'
88	);
89}
90
91if(function_exists('mysql_connect'))
92{
93	$dboptions['mysql'] = array(
94		'class' => 'DB_MySQL',
95		'title' => 'MySQL',
96		'short_title' => 'MySQL',
97		'structure_file' => 'mysql_db_tables.php',
98		'population_file' => 'mysql_db_inserts.php'
99	);
100}
101
102if(function_exists('pg_connect'))
103{
104	$dboptions['pgsql'] = array(
105		'class' => 'DB_PgSQL',
106		'title' => 'PostgreSQL',
107		'short_title' => 'PostgreSQL',
108		'structure_file' => 'pgsql_db_tables.php',
109		'population_file' => 'pgsql_db_inserts.php'
110	);
111}
112
113if(class_exists('PDO'))
114{
115	$supported_dbs = PDO::getAvailableDrivers();
116	if(in_array('sqlite', $supported_dbs))
117	{
118		$dboptions['sqlite'] = array(
119			'class' => 'DB_SQLite',
120			'title' => 'SQLite 3',
121			'short_title' => 'SQLite',
122			'structure_file' => 'sqlite_db_tables.php',
123			'population_file' => 'pgsql_db_inserts.php'
124		);
125	}
126
127	if (in_array('pgsql', $supported_dbs)) {
128		$dboptions['pgsql_pdo'] = array(
129			'class' => 'PostgresPdoDbDriver',
130			'title' => 'PostgreSQL (PDO)',
131			'short_title' => 'PostgreSQL (PDO)',
132			'structure_file' => 'pgsql_db_tables.php',
133			'population_file' => 'pgsql_db_inserts.php'
134		);
135	}
136
137	if (in_array('mysql', $supported_dbs)) {
138		$dboptions['mysql_pdo'] = array(
139			'class' => 'MysqlPdoDbDriver',
140			'title' => 'MySQL (PDO)',
141			'short_title' => 'MySQL (PDO)',
142			'structure_file' => 'mysql_db_tables.php',
143			'population_file' => 'mysql_db_inserts.php'
144		);
145	}
146}
147
148if(file_exists('lock') && $mybb->dev_mode != true)
149{
150	$output->print_error($lang->locked);
151}
152else if($installed == true && empty($mybb->input['action']))
153{
154	$output->print_header($lang->already_installed, "errormsg", 0);
155	echo $lang->sprintf($lang->mybb_already_installed, $mybb->version);
156	$output->print_footer();
157}
158else
159{
160	$output->steps = array(
161		'intro' => $lang->welcome,
162		'license' => $lang->license_agreement,
163		'requirements_check' => $lang->req_check,
164		'database_info' => $lang->db_config,
165		'create_tables' => $lang->table_creation,
166		'populate_tables' => $lang->data_insertion,
167		'templates' => $lang->theme_install,
168		'configuration' => $lang->board_config,
169		'adminuser' => $lang->admin_user,
170		'final' => $lang->finish_setup,
171	);
172
173	switch($mybb->get_input('action'))
174	{
175		case 'license':
176			license_agreement();
177			break;
178		case 'requirements_check':
179			requirements_check();
180			break;
181		case 'database_info':
182			database_info();
183			break;
184		case 'create_tables':
185			create_tables();
186			break;
187		case 'populate_tables':
188			populate_tables();
189			break;
190		case 'templates':
191			insert_templates();
192			break;
193		case 'configuration':
194			configure();
195			break;
196		case 'adminuser':
197			create_admin_user();
198			break;
199		case 'final':
200			install_done();
201			break;
202		default:
203			$mybb->input['action'] = 'intro';
204			intro();
205			break;
206	}
207}
208
209/**
210 * Welcome page
211 */
212function intro()
213{
214	global $output, $mybb, $lang;
215
216	$output->print_header();
217	if(strpos(strtolower(get_current_location('', '', true)), '/upload/') !== false)
218	{
219		echo $lang->sprintf($lang->mybb_incorrect_folder);
220	}
221	echo $lang->sprintf($lang->welcome_step, $mybb->version);
222	$output->print_footer('license');
223}
224
225/**
226 * Show the license agreement
227 */
228function license_agreement()
229{
230	global $output, $lang, $mybb;
231
232	ob_start();
233	$output->print_header($lang->license_agreement, 'license');
234
235	if($mybb->get_input('allow_anonymous_info', MyBB::INPUT_INT) == 1)
236	{
237		require_once MYBB_ROOT."inc/functions_serverstats.php";
238		$build_server_stats = build_server_stats(1, '', $mybb->version_code);
239
240		if($build_server_stats['info_sent_success'] == false)
241		{
242			echo $build_server_stats['info_image'];
243		}
244	}
245	ob_end_flush();
246
247	$license = <<<EOF
248<pre>
249                   GNU LESSER GENERAL PUBLIC LICENSE
250                       Version 3, 29 June 2007
251
252 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
253 Everyone is permitted to copy and distribute verbatim copies
254 of this license document, but changing it is not allowed.
255
256
257  This version of the GNU Lesser General Public License incorporates
258the terms and conditions of version 3 of the GNU General Public
259License, supplemented by the additional permissions listed below.
260
261  0. Additional Definitions.
262
263  As used herein, "this License" refers to version 3 of the GNU Lesser
264General Public License, and the "GNU GPL" refers to version 3 of the GNU
265General Public License.
266
267  "The Library" refers to a covered work governed by this License,
268other than an Application or a Combined Work as defined below.
269
270  An "Application" is any work that makes use of an interface provided
271by the Library, but which is not otherwise based on the Library.
272Defining a subclass of a class defined by the Library is deemed a mode
273of using an interface provided by the Library.
274
275  A "Combined Work" is a work produced by combining or linking an
276Application with the Library.  The particular version of the Library
277with which the Combined Work was made is also called the "Linked
278Version".
279
280  The "Minimal Corresponding Source" for a Combined Work means the
281Corresponding Source for the Combined Work, excluding any source code
282for portions of the Combined Work that, considered in isolation, are
283based on the Application, and not on the Linked Version.
284
285  The "Corresponding Application Code" for a Combined Work means the
286object code and/or source code for the Application, including any data
287and utility programs needed for reproducing the Combined Work from the
288Application, but excluding the System Libraries of the Combined Work.
289
290  1. Exception to Section 3 of the GNU GPL.
291
292  You may convey a covered work under sections 3 and 4 of this License
293without being bound by section 3 of the GNU GPL.
294
295  2. Conveying Modified Versions.
296
297  If you modify a copy of the Library, and, in your modifications, a
298facility refers to a function or data to be supplied by an Application
299that uses the facility (other than as an argument passed when the
300facility is invoked), then you may convey a copy of the modified
301version:
302
303   a) under this License, provided that you make a good faith effort to
304   ensure that, in the event an Application does not supply the
305   function or data, the facility still operates, and performs
306   whatever part of its purpose remains meaningful, or
307
308   b) under the GNU GPL, with none of the additional permissions of
309   this License applicable to that copy.
310
311  3. Object Code Incorporating Material from Library Header Files.
312
313  The object code form of an Application may incorporate material from
314a header file that is part of the Library.  You may convey such object
315code under terms of your choice, provided that, if the incorporated
316material is not limited to numerical parameters, data structure
317layouts and accessors, or small macros, inline functions and templates
318(ten or fewer lines in length), you do both of the following:
319
320   a) Give prominent notice with each copy of the object code that the
321   Library is used in it and that the Library and its use are
322   covered by this License.
323
324   b) Accompany the object code with a copy of the GNU GPL and this license
325   document.
326
327  4. Combined Works.
328
329  You may convey a Combined Work under terms of your choice that,
330taken together, effectively do not restrict modification of the
331portions of the Library contained in the Combined Work and reverse
332engineering for debugging such modifications, if you also do each of
333the following:
334
335   a) Give prominent notice with each copy of the Combined Work that
336   the Library is used in it and that the Library and its use are
337   covered by this License.
338
339   b) Accompany the Combined Work with a copy of the GNU GPL and this license
340   document.
341
342   c) For a Combined Work that displays copyright notices during
343   execution, include the copyright notice for the Library among
344   these notices, as well as a reference directing the user to the
345   copies of the GNU GPL and this license document.
346
347   d) Do one of the following:
348
349       0) Convey the Minimal Corresponding Source under the terms of this
350       License, and the Corresponding Application Code in a form
351       suitable for, and under terms that permit, the user to
352       recombine or relink the Application with a modified version of
353       the Linked Version to produce a modified Combined Work, in the
354       manner specified by section 6 of the GNU GPL for conveying
355       Corresponding Source.
356
357       1) Use a suitable shared library mechanism for linking with the
358       Library.  A suitable mechanism is one that (a) uses at run time
359       a copy of the Library already present on the user's computer
360       system, and (b) will operate properly with a modified version
361       of the Library that is interface-compatible with the Linked
362       Version.
363
364   e) Provide Installation Information, but only if you would otherwise
365   be required to provide such information under section 6 of the
366   GNU GPL, and only to the extent that such information is
367   necessary to install and execute a modified version of the
368   Combined Work produced by recombining or relinking the
369   Application with a modified version of the Linked Version. (If
370   you use option 4d0, the Installation Information must accompany
371   the Minimal Corresponding Source and Corresponding Application
372   Code. If you use option 4d1, you must provide the Installation
373   Information in the manner specified by section 6 of the GNU GPL
374   for conveying Corresponding Source.)
375
376  5. Combined Libraries.
377
378  You may place library facilities that are a work based on the
379Library side by side in a single library together with other library
380facilities that are not Applications and are not covered by this
381License, and convey such a combined library under terms of your
382choice, if you do both of the following:
383
384   a) Accompany the combined library with a copy of the same work based
385   on the Library, uncombined with any other library facilities,
386   conveyed under the terms of this License.
387
388   b) Give prominent notice with the combined library that part of it
389   is a work based on the Library, and explaining where to find the
390   accompanying uncombined form of the same work.
391
392  6. Revised Versions of the GNU Lesser General Public License.
393
394  The Free Software Foundation may publish revised and/or new versions
395of the GNU Lesser General Public License from time to time. Such new
396versions will be similar in spirit to the present version, but may
397differ in detail to address new problems or concerns.
398
399  Each version is given a distinguishing version number. If the
400Library as you received it specifies that a certain numbered version
401of the GNU Lesser General Public License "or any later version"
402applies to it, you have the option of following the terms and
403conditions either of that published version or of any later version
404published by the Free Software Foundation. If the Library as you
405received it does not specify a version number of the GNU Lesser
406General Public License, you may choose any version of the GNU Lesser
407General Public License ever published by the Free Software Foundation.
408
409  If the Library as you received it specifies that a proxy can decide
410whether future versions of the GNU Lesser General Public License shall
411apply, that proxy's public statement of acceptance of any version is
412permanent authorization for you to choose that version for the
413Library.
414
415                    GNU GENERAL PUBLIC LICENSE
416                       Version 3, 29 June 2007
417
418 Copyright (C) 2007 Free Software Foundation, Inc. &lt;http://fsf.org/&gt;
419 Everyone is permitted to copy and distribute verbatim copies
420 of this license document, but changing it is not allowed.
421
422                            Preamble
423
424  The GNU General Public License is a free, copyleft license for
425software and other kinds of works.
426
427  The licenses for most software and other practical works are designed
428to take away your freedom to share and change the works.  By contrast,
429the GNU General Public License is intended to guarantee your freedom to
430share and change all versions of a program--to make sure it remains free
431software for all its users.  We, the Free Software Foundation, use the
432GNU General Public License for most of our software; it applies also to
433any other work released this way by its authors.  You can apply it to
434your programs, too.
435
436  When we speak of free software, we are referring to freedom, not
437price.  Our General Public Licenses are designed to make sure that you
438have the freedom to distribute copies of free software (and charge for
439them if you wish), that you receive source code or can get it if you
440want it, that you can change the software or use pieces of it in new
441free programs, and that you know you can do these things.
442
443  To protect your rights, we need to prevent others from denying you
444these rights or asking you to surrender the rights.  Therefore, you have
445certain responsibilities if you distribute copies of the software, or if
446you modify it: responsibilities to respect the freedom of others.
447
448  For example, if you distribute copies of such a program, whether
449gratis or for a fee, you must pass on to the recipients the same
450freedoms that you received.  You must make sure that they, too, receive
451or can get the source code.  And you must show them these terms so they
452know their rights.
453
454  Developers that use the GNU GPL protect your rights with two steps:
455(1) assert copyright on the software, and (2) offer you this License
456giving you legal permission to copy, distribute and/or modify it.
457
458  For the developers' and authors' protection, the GPL clearly explains
459that there is no warranty for this free software.  For both users' and
460authors' sake, the GPL requires that modified versions be marked as
461changed, so that their problems will not be attributed erroneously to
462authors of previous versions.
463
464  Some devices are designed to deny users access to install or run
465modified versions of the software inside them, although the manufacturer
466can do so.  This is fundamentally incompatible with the aim of
467protecting users' freedom to change the software.  The systematic
468pattern of such abuse occurs in the area of products for individuals to
469use, which is precisely where it is most unacceptable.  Therefore, we
470have designed this version of the GPL to prohibit the practice for those
471products.  If such problems arise substantially in other domains, we
472stand ready to extend this provision to those domains in future versions
473of the GPL, as needed to protect the freedom of users.
474
475  Finally, every program is threatened constantly by software patents.
476States should not allow patents to restrict development and use of
477software on general-purpose computers, but in those that do, we wish to
478avoid the special danger that patents applied to a free program could
479make it effectively proprietary.  To prevent this, the GPL assures that
480patents cannot be used to render the program non-free.
481
482  The precise terms and conditions for copying, distribution and
483modification follow.
484
485                       TERMS AND CONDITIONS
486
487  0. Definitions.
488
489  "This License" refers to version 3 of the GNU General Public License.
490
491  "Copyright" also means copyright-like laws that apply to other kinds of
492works, such as semiconductor masks.
493
494  "The Program" refers to any copyrightable work licensed under this
495License.  Each licensee is addressed as "you".  "Licensees" and
496"recipients" may be individuals or organizations.
497
498  To "modify" a work means to copy from or adapt all or part of the work
499in a fashion requiring copyright permission, other than the making of an
500exact copy.  The resulting work is called a "modified version" of the
501earlier work or a work "based on" the earlier work.
502
503  A "covered work" means either the unmodified Program or a work based
504on the Program.
505
506  To "propagate" a work means to do anything with it that, without
507permission, would make you directly or secondarily liable for
508infringement under applicable copyright law, except executing it on a
509computer or modifying a private copy.  Propagation includes copying,
510distribution (with or without modification), making available to the
511public, and in some countries other activities as well.
512
513  To "convey" a work means any kind of propagation that enables other
514parties to make or receive copies.  Mere interaction with a user through
515a computer network, with no transfer of a copy, is not conveying.
516
517  An interactive user interface displays "Appropriate Legal Notices"
518to the extent that it includes a convenient and prominently visible
519feature that (1) displays an appropriate copyright notice, and (2)
520tells the user that there is no warranty for the work (except to the
521extent that warranties are provided), that licensees may convey the
522work under this License, and how to view a copy of this License.  If
523the interface presents a list of user commands or options, such as a
524menu, a prominent item in the list meets this criterion.
525
526  1. Source Code.
527
528  The "source code" for a work means the preferred form of the work
529for making modifications to it.  "Object code" means any non-source
530form of a work.
531
532  A "Standard Interface" means an interface that either is an official
533standard defined by a recognized standards body, or, in the case of
534interfaces specified for a particular programming language, one that
535is widely used among developers working in that language.
536
537  The "System Libraries" of an executable work include anything, other
538than the work as a whole, that (a) is included in the normal form of
539packaging a Major Component, but which is not part of that Major
540Component, and (b) serves only to enable use of the work with that
541Major Component, or to implement a Standard Interface for which an
542implementation is available to the public in source code form.  A
543"Major Component", in this context, means a major essential component
544(kernel, window system, and so on) of the specific operating system
545(if any) on which the executable work runs, or a compiler used to
546produce the work, or an object code interpreter used to run it.
547
548  The "Corresponding Source" for a work in object code form means all
549the source code needed to generate, install, and (for an executable
550work) run the object code and to modify the work, including scripts to
551control those activities.  However, it does not include the work's
552System Libraries, or general-purpose tools or generally available free
553programs which are used unmodified in performing those activities but
554which are not part of the work.  For example, Corresponding Source
555includes interface definition files associated with source files for
556the work, and the source code for shared libraries and dynamically
557linked subprograms that the work is specifically designed to require,
558such as by intimate data communication or control flow between those
559subprograms and other parts of the work.
560
561  The Corresponding Source need not include anything that users
562can regenerate automatically from other parts of the Corresponding
563Source.
564
565  The Corresponding Source for a work in source code form is that
566same work.
567
568  2. Basic Permissions.
569
570  All rights granted under this License are granted for the term of
571copyright on the Program, and are irrevocable provided the stated
572conditions are met.  This License explicitly affirms your unlimited
573permission to run the unmodified Program.  The output from running a
574covered work is covered by this License only if the output, given its
575content, constitutes a covered work.  This License acknowledges your
576rights of fair use or other equivalent, as provided by copyright law.
577
578  You may make, run and propagate covered works that you do not
579convey, without conditions so long as your license otherwise remains
580in force.  You may convey covered works to others for the sole purpose
581of having them make modifications exclusively for you, or provide you
582with facilities for running those works, provided that you comply with
583the terms of this License in conveying all material for which you do
584not control copyright.  Those thus making or running the covered works
585for you must do so exclusively on your behalf, under your direction
586and control, on terms that prohibit them from making any copies of
587your copyrighted material outside their relationship with you.
588
589  Conveying under any other circumstances is permitted solely under
590the conditions stated below.  Sublicensing is not allowed; section 10
591makes it unnecessary.
592
593  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
594
595  No covered work shall be deemed part of an effective technological
596measure under any applicable law fulfilling obligations under article
59711 of the WIPO copyright treaty adopted on 20 December 1996, or
598similar laws prohibiting or restricting circumvention of such
599measures.
600
601  When you convey a covered work, you waive any legal power to forbid
602circumvention of technological measures to the extent such circumvention
603is effected by exercising rights under this License with respect to
604the covered work, and you disclaim any intention to limit operation or
605modification of the work as a means of enforcing, against the work's
606users, your or third parties' legal rights to forbid circumvention of
607technological measures.
608
609  4. Conveying Verbatim Copies.
610
611  You may convey verbatim copies of the Program's source code as you
612receive it, in any medium, provided that you conspicuously and
613appropriately publish on each copy an appropriate copyright notice;
614keep intact all notices stating that this License and any
615non-permissive terms added in accord with section 7 apply to the code;
616keep intact all notices of the absence of any warranty; and give all
617recipients a copy of this License along with the Program.
618
619  You may charge any price or no price for each copy that you convey,
620and you may offer support or warranty protection for a fee.
621
622  5. Conveying Modified Source Versions.
623
624  You may convey a work based on the Program, or the modifications to
625produce it from the Program, in the form of source code under the
626terms of section 4, provided that you also meet all of these conditions:
627
628    a) The work must carry prominent notices stating that you modified
629    it, and giving a relevant date.
630
631    b) The work must carry prominent notices stating that it is
632    released under this License and any conditions added under section
633    7.  This requirement modifies the requirement in section 4 to
634    "keep intact all notices".
635
636    c) You must license the entire work, as a whole, under this
637    License to anyone who comes into possession of a copy.  This
638    License will therefore apply, along with any applicable section 7
639    additional terms, to the whole of the work, and all its parts,
640    regardless of how they are packaged.  This License gives no
641    permission to license the work in any other way, but it does not
642    invalidate such permission if you have separately received it.
643
644    d) If the work has interactive user interfaces, each must display
645    Appropriate Legal Notices; however, if the Program has interactive
646    interfaces that do not display Appropriate Legal Notices, your
647    work need not make them do so.
648
649  A compilation of a covered work with other separate and independent
650works, which are not by their nature extensions of the covered work,
651and which are not combined with it such as to form a larger program,
652in or on a volume of a storage or distribution medium, is called an
653"aggregate" if the compilation and its resulting copyright are not
654used to limit the access or legal rights of the compilation's users
655beyond what the individual works permit.  Inclusion of a covered work
656in an aggregate does not cause this License to apply to the other
657parts of the aggregate.
658
659  6. Conveying Non-Source Forms.
660
661  You may convey a covered work in object code form under the terms
662of sections 4 and 5, provided that you also convey the
663machine-readable Corresponding Source under the terms of this License,
664in one of these ways:
665
666    a) Convey the object code in, or embodied in, a physical product
667    (including a physical distribution medium), accompanied by the
668    Corresponding Source fixed on a durable physical medium
669    customarily used for software interchange.
670
671    b) Convey the object code in, or embodied in, a physical product
672    (including a physical distribution medium), accompanied by a
673    written offer, valid for at least three years and valid for as
674    long as you offer spare parts or customer support for that product
675    model, to give anyone who possesses the object code either (1) a
676    copy of the Corresponding Source for all the software in the
677    product that is covered by this License, on a durable physical
678    medium customarily used for software interchange, for a price no
679    more than your reasonable cost of physically performing this
680    conveying of source, or (2) access to copy the
681    Corresponding Source from a network server at no charge.
682
683    c) Convey individual copies of the object code with a copy of the
684    written offer to provide the Corresponding Source.  This
685    alternative is allowed only occasionally and noncommercially, and
686    only if you received the object code with such an offer, in accord
687    with subsection 6b.
688
689    d) Convey the object code by offering access from a designated
690    place (gratis or for a charge), and offer equivalent access to the
691    Corresponding Source in the same way through the same place at no
692    further charge.  You need not require recipients to copy the
693    Corresponding Source along with the object code.  If the place to
694    copy the object code is a network server, the Corresponding Source
695    may be on a different server (operated by you or a third party)
696    that supports equivalent copying facilities, provided you maintain
697    clear directions next to the object code saying where to find the
698    Corresponding Source.  Regardless of what server hosts the
699    Corresponding Source, you remain obligated to ensure that it is
700    available for as long as needed to satisfy these requirements.
701
702    e) Convey the object code using peer-to-peer transmission, provided
703    you inform other peers where the object code and Corresponding
704    Source of the work are being offered to the general public at no
705    charge under subsection 6d.
706
707  A separable portion of the object code, whose source code is excluded
708from the Corresponding Source as a System Library, need not be
709included in conveying the object code work.
710
711  A "User Product" is either (1) a "consumer product", which means any
712tangible personal property which is normally used for personal, family,
713or household purposes, or (2) anything designed or sold for incorporation
714into a dwelling.  In determining whether a product is a consumer product,
715doubtful cases shall be resolved in favor of coverage.  For a particular
716product received by a particular user, "normally used" refers to a
717typical or common use of that class of product, regardless of the status
718of the particular user or of the way in which the particular user
719actually uses, or expects or is expected to use, the product.  A product
720is a consumer product regardless of whether the product has substantial
721commercial, industrial or non-consumer uses, unless such uses represent
722the only significant mode of use of the product.
723
724  "Installation Information" for a User Product means any methods,
725procedures, authorization keys, or other information required to install
726and execute modified versions of a covered work in that User Product from
727a modified version of its Corresponding Source.  The information must
728suffice to ensure that the continued functioning of the modified object
729code is in no case prevented or interfered with solely because
730modification has been made.
731
732  If you convey an object code work under this section in, or with, or
733specifically for use in, a User Product, and the conveying occurs as
734part of a transaction in which the right of possession and use of the
735User Product is transferred to the recipient in perpetuity or for a
736fixed term (regardless of how the transaction is characterized), the
737Corresponding Source conveyed under this section must be accompanied
738by the Installation Information.  But this requirement does not apply
739if neither you nor any third party retains the ability to install
740modified object code on the User Product (for example, the work has
741been installed in ROM).
742
743  The requirement to provide Installation Information does not include a
744requirement to continue to provide support service, warranty, or updates
745for a work that has been modified or installed by the recipient, or for
746the User Product in which it has been modified or installed.  Access to a
747network may be denied when the modification itself materially and
748adversely affects the operation of the network or violates the rules and
749protocols for communication across the network.
750
751  Corresponding Source conveyed, and Installation Information provided,
752in accord with this section must be in a format that is publicly
753documented (and with an implementation available to the public in
754source code form), and must require no special password or key for
755unpacking, reading or copying.
756
757  7. Additional Terms.
758
759  "Additional permissions" are terms that supplement the terms of this
760License by making exceptions from one or more of its conditions.
761Additional permissions that are applicable to the entire Program shall
762be treated as though they were included in this License, to the extent
763that they are valid under applicable law.  If additional permissions
764apply only to part of the Program, that part may be used separately
765under those permissions, but the entire Program remains governed by
766this License without regard to the additional permissions.
767
768  When you convey a copy of a covered work, you may at your option
769remove any additional permissions from that copy, or from any part of
770it.  (Additional permissions may be written to require their own
771removal in certain cases when you modify the work.)  You may place
772additional permissions on material, added by you to a covered work,
773for which you have or can give appropriate copyright permission.
774
775  Notwithstanding any other provision of this License, for material you
776add to a covered work, you may (if authorized by the copyright holders of
777that material) supplement the terms of this License with terms:
778
779    a) Disclaiming warranty or limiting liability differently from the
780    terms of sections 15 and 16 of this License; or
781
782    b) Requiring preservation of specified reasonable legal notices or
783    author attributions in that material or in the Appropriate Legal
784    Notices displayed by works containing it; or
785
786    c) Prohibiting misrepresentation of the origin of that material, or
787    requiring that modified versions of such material be marked in
788    reasonable ways as different from the original version; or
789
790    d) Limiting the use for publicity purposes of names of licensors or
791    authors of the material; or
792
793    e) Declining to grant rights under trademark law for use of some
794    trade names, trademarks, or service marks; or
795
796    f) Requiring indemnification of licensors and authors of that
797    material by anyone who conveys the material (or modified versions of
798    it) with contractual assumptions of liability to the recipient, for
799    any liability that these contractual assumptions directly impose on
800    those licensors and authors.
801
802  All other non-permissive additional terms are considered "further
803restrictions" within the meaning of section 10.  If the Program as you
804received it, or any part of it, contains a notice stating that it is
805governed by this License along with a term that is a further
806restriction, you may remove that term.  If a license document contains
807a further restriction but permits relicensing or conveying under this
808License, you may add to a covered work material governed by the terms
809of that license document, provided that the further restriction does
810not survive such relicensing or conveying.
811
812  If you add terms to a covered work in accord with this section, you
813must place, in the relevant source files, a statement of the
814additional terms that apply to those files, or a notice indicating
815where to find the applicable terms.
816
817  Additional terms, permissive or non-permissive, may be stated in the
818form of a separately written license, or stated as exceptions;
819the above requirements apply either way.
820
821  8. Termination.
822
823  You may not propagate or modify a covered work except as expressly
824provided under this License.  Any attempt otherwise to propagate or
825modify it is void, and will automatically terminate your rights under
826this License (including any patent licenses granted under the third
827paragraph of section 11).
828
829  However, if you cease all violation of this License, then your
830license from a particular copyright holder is reinstated (a)
831provisionally, unless and until the copyright holder explicitly and
832finally terminates your license, and (b) permanently, if the copyright
833holder fails to notify you of the violation by some reasonable means
834prior to 60 days after the cessation.
835
836  Moreover, your license from a particular copyright holder is
837reinstated permanently if the copyright holder notifies you of the
838violation by some reasonable means, this is the first time you have
839received notice of violation of this License (for any work) from that
840copyright holder, and you cure the violation prior to 30 days after
841your receipt of the notice.
842
843  Termination of your rights under this section does not terminate the
844licenses of parties who have received copies or rights from you under
845this License.  If your rights have been terminated and not permanently
846reinstated, you do not qualify to receive new licenses for the same
847material under section 10.
848
849  9. Acceptance Not Required for Having Copies.
850
851  You are not required to accept this License in order to receive or
852run a copy of the Program.  Ancillary propagation of a covered work
853occurring solely as a consequence of using peer-to-peer transmission
854to receive a copy likewise does not require acceptance.  However,
855nothing other than this License grants you permission to propagate or
856modify any covered work.  These actions infringe copyright if you do
857not accept this License.  Therefore, by modifying or propagating a
858covered work, you indicate your acceptance of this License to do so.
859
860  10. Automatic Licensing of Downstream Recipients.
861
862  Each time you convey a covered work, the recipient automatically
863receives a license from the original licensors, to run, modify and
864propagate that work, subject to this License.  You are not responsible
865for enforcing compliance by third parties with this License.
866
867  An "entity transaction" is a transaction transferring control of an
868organization, or substantially all assets of one, or subdividing an
869organization, or merging organizations.  If propagation of a covered
870work results from an entity transaction, each party to that
871transaction who receives a copy of the work also receives whatever
872licenses to the work the party's predecessor in interest had or could
873give under the previous paragraph, plus a right to possession of the
874Corresponding Source of the work from the predecessor in interest, if
875the predecessor has it or can get it with reasonable efforts.
876
877  You may not impose any further restrictions on the exercise of the
878rights granted or affirmed under this License.  For example, you may
879not impose a license fee, royalty, or other charge for exercise of
880rights granted under this License, and you may not initiate litigation
881(including a cross-claim or counterclaim in a lawsuit) alleging that
882any patent claim is infringed by making, using, selling, offering for
883sale, or importing the Program or any portion of it.
884
885  11. Patents.
886
887  A "contributor" is a copyright holder who authorizes use under this
888License of the Program or a work on which the Program is based.  The
889work thus licensed is called the contributor's "contributor version".
890
891  A contributor's "essential patent claims" are all patent claims
892owned or controlled by the contributor, whether already acquired or
893hereafter acquired, that would be infringed by some manner, permitted
894by this License, of making, using, or selling its contributor version,
895but do not include claims that would be infringed only as a
896consequence of further modification of the contributor version.  For
897purposes of this definition, "control" includes the right to grant
898patent sublicenses in a manner consistent with the requirements of
899this License.
900
901  Each contributor grants you a non-exclusive, worldwide, royalty-free
902patent license under the contributor's essential patent claims, to
903make, use, sell, offer for sale, import and otherwise run, modify and
904propagate the contents of its contributor version.
905
906  In the following three paragraphs, a "patent license" is any express
907agreement or commitment, however denominated, not to enforce a patent
908(such as an express permission to practice a patent or covenant not to
909sue for patent infringement).  To "grant" such a patent license to a
910party means to make such an agreement or commitment not to enforce a
911patent against the party.
912
913  If you convey a covered work, knowingly relying on a patent license,
914and the Corresponding Source of the work is not available for anyone
915to copy, free of charge and under the terms of this License, through a
916publicly available network server or other readily accessible means,
917then you must either (1) cause the Corresponding Source to be so
918available, or (2) arrange to deprive yourself of the benefit of the
919patent license for this particular work, or (3) arrange, in a manner
920consistent with the requirements of this License, to extend the patent
921license to downstream recipients.  "Knowingly relying" means you have
922actual knowledge that, but for the patent license, your conveying the
923covered work in a country, or your recipient's use of the covered work
924in a country, would infringe one or more identifiable patents in that
925country that you have reason to believe are valid.
926
927  If, pursuant to or in connection with a single transaction or
928arrangement, you convey, or propagate by procuring conveyance of, a
929covered work, and grant a patent license to some of the parties
930receiving the covered work authorizing them to use, propagate, modify
931or convey a specific copy of the covered work, then the patent license
932you grant is automatically extended to all recipients of the covered
933work and works based on it.
934
935  A patent license is "discriminatory" if it does not include within
936the scope of its coverage, prohibits the exercise of, or is
937conditioned on the non-exercise of one or more of the rights that are
938specifically granted under this License.  You may not convey a covered
939work if you are a party to an arrangement with a third party that is
940in the business of distributing software, under which you make payment
941to the third party based on the extent of your activity of conveying
942the work, and under which the third party grants, to any of the
943parties who would receive the covered work from you, a discriminatory
944patent license (a) in connection with copies of the covered work
945conveyed by you (or copies made from those copies), or (b) primarily
946for and in connection with specific products or compilations that
947contain the covered work, unless you entered into that arrangement,
948or that patent license was granted, prior to 28 March 2007.
949
950  Nothing in this License shall be construed as excluding or limiting
951any implied license or other defenses to infringement that may
952otherwise be available to you under applicable patent law.
953
954  12. No Surrender of Others' Freedom.
955
956  If conditions are imposed on you (whether by court order, agreement or
957otherwise) that contradict the conditions of this License, they do not
958excuse you from the conditions of this License.  If you cannot convey a
959covered work so as to satisfy simultaneously your obligations under this
960License and any other pertinent obligations, then as a consequence you may
961not convey it at all.  For example, if you agree to terms that obligate you
962to collect a royalty for further conveying from those to whom you convey
963the Program, the only way you could satisfy both those terms and this
964License would be to refrain entirely from conveying the Program.
965
966  13. Use with the GNU Affero General Public License.
967
968  Notwithstanding any other provision of this License, you have
969permission to link or combine any covered work with a work licensed
970under version 3 of the GNU Affero General Public License into a single
971combined work, and to convey the resulting work.  The terms of this
972License will continue to apply to the part which is the covered work,
973but the special requirements of the GNU Affero General Public License,
974section 13, concerning interaction through a network will apply to the
975combination as such.
976
977  14. Revised Versions of this License.
978
979  The Free Software Foundation may publish revised and/or new versions of
980the GNU General Public License from time to time.  Such new versions will
981be similar in spirit to the present version, but may differ in detail to
982address new problems or concerns.
983
984  Each version is given a distinguishing version number.  If the
985Program specifies that a certain numbered version of the GNU General
986Public License "or any later version" applies to it, you have the
987option of following the terms and conditions either of that numbered
988version or of any later version published by the Free Software
989Foundation.  If the Program does not specify a version number of the
990GNU General Public License, you may choose any version ever published
991by the Free Software Foundation.
992
993  If the Program specifies that a proxy can decide which future
994versions of the GNU General Public License can be used, that proxy's
995public statement of acceptance of a version permanently authorizes you
996to choose that version for the Program.
997
998  Later license versions may give you additional or different
999permissions.  However, no additional obligations are imposed on any
1000author or copyright holder as a result of your choosing to follow a
1001later version.
1002
1003  15. Disclaimer of Warranty.
1004
1005  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
1006APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
1007HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
1008OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
1009THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1010PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
1011IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
1012ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
1013
1014  16. Limitation of Liability.
1015
1016  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
1017WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
1018THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
1019GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
1020USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
1021DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
1022PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
1023EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
1024SUCH DAMAGES.
1025
1026  17. Interpretation of Sections 15 and 16.
1027
1028  If the disclaimer of warranty and limitation of liability provided
1029above cannot be given local legal effect according to their terms,
1030reviewing courts shall apply local law that most closely approximates
1031an absolute waiver of all civil liability in connection with the
1032Program, unless a warranty or assumption of liability accompanies a
1033copy of the Program in return for a fee.
1034
1035                     END OF TERMS AND CONDITIONS
1036</pre>
1037EOF;
1038	echo $lang->sprintf($lang->license_step, $license);
1039	$output->print_footer('requirements_check');
1040}
1041
1042/**
1043 * Check our requirements
1044 */
1045function requirements_check()
1046{
1047	global $output, $mybb, $dboptions, $lang;
1048
1049	$mybb->input['action'] = "requirements_check";
1050	$output->print_header($lang->req_check, 'requirements');
1051	echo $lang->req_step_top;
1052	$errors = array();
1053	$showerror = 0;
1054
1055	if(!file_exists(MYBB_ROOT."/inc/config.php"))
1056	{
1057		if(!@rename(MYBB_ROOT."/inc/config.default.php", MYBB_ROOT."/inc/config.php"))
1058		{
1059			if(!$configwritable)
1060			{
1061				$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_configdefaultfile);
1062				$configstatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_writable);
1063				$showerror = 1;
1064			}
1065		}
1066	}
1067
1068	// Check PHP Version
1069	if(version_compare(PHP_VERSION, '5.2.0', "<"))
1070	{
1071		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->sprintf($lang->req_step_error_phpversion, PHP_VERSION));
1072		$phpversion = $lang->sprintf($lang->req_step_span_fail, PHP_VERSION);
1073		$showerror = 1;
1074	}
1075	else
1076	{
1077		$phpversion = $lang->sprintf($lang->req_step_span_pass, PHP_VERSION);
1078	}
1079
1080	$mboptions = array();
1081
1082	if(function_exists('mb_detect_encoding'))
1083	{
1084		$mboptions[] = $lang->multi_byte;
1085	}
1086
1087	if(function_exists('iconv'))
1088	{
1089		$mboptions[] = 'iconv';
1090	}
1091
1092	// Check Multibyte extensions
1093	if(count($mboptions) < 1)
1094	{
1095		$mbstatus = $lang->sprintf($lang->req_step_span_fail, $lang->none);
1096	}
1097	else
1098	{
1099		$mbstatus = implode(', ', $mboptions);
1100	}
1101
1102	// Check database engines
1103	if(count($dboptions) < 1)
1104	{
1105		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_dboptions);
1106		$dbsupportlist = $lang->sprintf($lang->req_step_span_fail, $lang->none);
1107		$showerror = 1;
1108	}
1109	else
1110	{
1111		foreach($dboptions as $dboption)
1112		{
1113			$dbsupportlist[] = $dboption['title'];
1114		}
1115		$dbsupportlist = implode(', ', $dbsupportlist);
1116	}
1117
1118	// Check XML parser is installed
1119	if(!function_exists('xml_parser_create'))
1120	{
1121		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_xmlsupport);
1122		$xmlstatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_installed);
1123		$showerror = 1;
1124	}
1125	else
1126	{
1127		$xmlstatus = $lang->sprintf($lang->req_step_span_pass, $lang->installed);
1128	}
1129
1130	// Check config file is writable
1131	$configwritable = @fopen(MYBB_ROOT.'inc/config.php', 'w');
1132	if(!$configwritable)
1133	{
1134		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_configfile);
1135		$configstatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_writable);
1136		$showerror = 1;
1137	}
1138	else
1139	{
1140		$configstatus = $lang->sprintf($lang->req_step_span_pass, $lang->writable);
1141	}
1142	@fclose($configwritable);
1143
1144	// Check settings file is writable
1145	$settingswritable = @fopen(MYBB_ROOT.'inc/settings.php', 'w');
1146	if(!$settingswritable)
1147	{
1148		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_settingsfile);
1149		$settingsstatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_writable);
1150		$showerror = 1;
1151	}
1152	else
1153	{
1154		$settingsstatus = $lang->sprintf($lang->req_step_span_pass, $lang->writable);
1155	}
1156	@fclose($settingswritable);
1157
1158	// Check cache directory is writable
1159	$cachewritable = @fopen(MYBB_ROOT.'cache/test.write', 'w');
1160	if(!$cachewritable)
1161	{
1162		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_cachedir);
1163		$cachestatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_writable);
1164		$showerror = 1;
1165		@fclose($cachewritable);
1166	}
1167	else
1168	{
1169		$cachestatus = $lang->sprintf($lang->req_step_span_pass, $lang->writable);
1170		@fclose($cachewritable);
1171	  	@my_chmod(MYBB_ROOT.'cache', '0777');
1172	  	@my_chmod(MYBB_ROOT.'cache/test.write', '0777');
1173		@unlink(MYBB_ROOT.'cache/test.write');
1174	}
1175
1176	// Check upload directory is writable
1177	$uploadswritable = @fopen(MYBB_ROOT.'uploads/test.write', 'w');
1178	if(!$uploadswritable)
1179	{
1180		$errors[] = $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_uploaddir);
1181		$uploadsstatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_writable);
1182		$showerror = 1;
1183		@fclose($uploadswritable);
1184	}
1185	else
1186	{
1187		$uploadsstatus = $lang->sprintf($lang->req_step_span_pass, $lang->writable);
1188		@fclose($uploadswritable);
1189	  	@my_chmod(MYBB_ROOT.'uploads', '0777');
1190	  	@my_chmod(MYBB_ROOT.'uploads/test.write', '0777');
1191		@unlink(MYBB_ROOT.'uploads/test.write');
1192	}
1193
1194	// Check avatar directory is writable
1195	$avatarswritable = @fopen(MYBB_ROOT.'uploads/avatars/test.write', 'w');
1196	if(!$avatarswritable)
1197	{
1198		$errors[] =  $lang->sprintf($lang->req_step_error_box, $lang->req_step_error_avatardir);
1199		$avatarsstatus = $lang->sprintf($lang->req_step_span_fail, $lang->not_writable);
1200		$showerror = 1;
1201		@fclose($avatarswritable);
1202	}
1203	else
1204	{
1205		$avatarsstatus = $lang->sprintf($lang->req_step_span_pass, $lang->writable);
1206		@fclose($avatarswritable);
1207		@my_chmod(MYBB_ROOT.'uploads/avatars', '0777');
1208	  	@my_chmod(MYBB_ROOT.'uploads/avatars/test.write', '0777');
1209		@unlink(MYBB_ROOT.'uploads/avatars/test.write');
1210  	}
1211
1212	// Output requirements page
1213	echo $lang->sprintf($lang->req_step_reqtable, $phpversion, $dbsupportlist, $mbstatus, $xmlstatus, $configstatus, $settingsstatus, $cachestatus, $uploadsstatus, $avatarsstatus);
1214
1215	if($showerror == 1)
1216	{
1217		$error_list = error_list($errors);
1218		echo $lang->sprintf($lang->req_step_error_tablelist, $error_list);
1219		echo "\n			<input type=\"hidden\" name=\"action\" value=\"{$mybb->input['action']}\" />";
1220		echo "\n				<div id=\"next_button\"><input type=\"submit\" class=\"submit_button\" value=\"{$lang->recheck} &raquo;\" /></div><br style=\"clear: both;\" />\n";
1221		$output->print_footer();
1222	}
1223	else
1224	{
1225		echo $lang->req_step_reqcomplete;
1226		$output->print_footer('database_info');
1227	}
1228}
1229
1230/**
1231 * Which database do we use?
1232 */
1233function database_info()
1234{
1235	global $output, $dbinfo, $errors, $mybb, $dboptions, $lang;
1236
1237	$mybb->input['action'] = 'database_info';
1238	$output->print_header($lang->db_config, 'dbconfig');
1239
1240	echo "<script type=\"text/javascript\">
1241		function updateDBSettings()
1242		{
1243			var dbengine = \$(\"#dbengine\").val();
1244			$('.db_settings').each(function()
1245			{
1246				var element = $(this);
1247				element.addClass('db_settings');
1248				if(dbengine+'_settings' == element.attr('id'))
1249				{
1250					element.show();
1251				}
1252				else
1253				{
1254					element.hide();
1255				}
1256			});
1257		}
1258		$(function()
1259		{
1260			updateDBSettings();
1261		});
1262		</script>";
1263
1264	// Check for errors from this stage
1265	if(is_array($errors))
1266	{
1267		$error_list = error_list($errors);
1268		echo $lang->sprintf($lang->db_step_error_config, $error_list);
1269	}
1270	else
1271	{
1272		echo $lang->db_step_config_db;
1273	}
1274
1275	$dbengines = '';
1276
1277	// Loop through database engines
1278	foreach($dboptions as $dbfile => $dbtype)
1279	{
1280		if($mybb->get_input('dbengine') == $dbfile)
1281		{
1282			$dbengines .= "<option value=\"{$dbfile}\" selected=\"selected\">{$dbtype['title']}</option>";
1283		}
1284		else
1285		{
1286			$dbengines .= "<option value=\"{$dbfile}\">{$dbtype['title']}</option>";
1287		}
1288	}
1289
1290	$db_info = array();
1291	foreach($dboptions as $dbfile => $dbtype)
1292	{
1293		require_once MYBB_ROOT."inc/db_{$dbfile}.php";
1294		$db = new $dbtype['class'];
1295		$encodings = $db->fetch_db_charsets();
1296		$encoding_select = '';
1297		$mybb->input['config'] = $mybb->get_input('config', MyBB::INPUT_ARRAY);
1298		if(empty($mybb->input['config'][$dbfile]['dbhost']))
1299		{
1300			$mybb->input['config'][$dbfile]['dbhost'] = "localhost";
1301		}
1302		if(empty($mybb->input['config'][$dbfile]['tableprefix']))
1303		{
1304			$mybb->input['config'][$dbfile]['tableprefix'] = "mybb_";
1305		}
1306		if(empty($mybb->input['config'][$dbfile]['dbname']))
1307		{
1308			$mybb->input['config'][$dbfile]['dbname'] = '';
1309		}
1310		if(empty($mybb->input['config'][$dbfile]['dbuser']))
1311		{
1312			$mybb->input['config'][$dbfile]['dbuser'] = '';
1313		}
1314		if(empty($mybb->input['config'][$dbfile]['dbpass']))
1315		{
1316			$mybb->input['config'][$dbfile]['dbpass'] = '';
1317		}
1318		if(empty($mybb->input['config'][$dbfile]['encoding']))
1319		{
1320			$mybb->input['config'][$dbfile]['encoding'] = "utf8";
1321		}
1322
1323		$class = '';
1324		if(empty($first) && !$mybb->get_input('dbengine'))
1325		{
1326			$mybb->input['dbengine'] = $dbfile;
1327			$first = true;
1328		}
1329		if($dbfile == $mybb->input['dbengine'])
1330		{
1331			$class = "_selected";
1332		}
1333
1334		$db_info[$dbfile] = "
1335			<tbody id=\"{$dbfile}_settings\" class=\"db_settings db_type{$class}\">
1336				<tr>
1337					<th colspan=\"2\" class=\"first last\">{$dbtype['title']} {$lang->database_settings}</th>
1338				</tr>";
1339
1340		// SQLite gets some special settings
1341		if($dbfile == 'sqlite')
1342		{
1343			$db_info[$dbfile] .= "
1344				<tr class=\"alt_row\">
1345					<td class=\"first\"><label for=\"config_{$dbfile}_dbname\">{$lang->database_path}</label></td>
1346					<td class=\"last alt_col\"><input type=\"text\" class=\"text_input\" name=\"config[{$dbfile}][dbname]\" id=\"config_{$dbfile}_dbname\" value=\"".htmlspecialchars_uni($mybb->input['config'][$dbfile]['dbname'])."\" /></td>
1347				</tr>";
1348		}
1349		// Others get db host, username, password etc
1350		else
1351		{
1352			$db_info[$dbfile] .= "
1353				<tr class=\"alt_row\">
1354					<td class=\"first\"><label for=\"config_{$dbfile}_dbhost\">{$lang->database_host}</label></td>
1355					<td class=\"last alt_col\"><input type=\"text\" class=\"text_input\" name=\"config[{$dbfile}][dbhost]\" id=\"config_{$dbfile}_dbhost\" value=\"".htmlspecialchars_uni($mybb->input['config'][$dbfile]['dbhost'])."\" /></td>
1356				</tr>
1357				<tr>
1358					<td class=\"first\"><label for=\"config_{$dbfile}_dbuser\">{$lang->database_user}</label></td>
1359					<td class=\"last alt_col\"><input type=\"text\" class=\"text_input\" name=\"config[{$dbfile}][dbuser]\" id=\"config_{$dbfile}_dbuser\" value=\"".htmlspecialchars_uni($mybb->input['config'][$dbfile]['dbuser'])."\" /></td>
1360				</tr>
1361				<tr class=\"alt_row\">
1362					<td class=\"first\"><label for=\"config_{$dbfile}_dbpass\">{$lang->database_pass}</label></td>
1363					<td class=\"last alt_col\"><input type=\"password\" class=\"text_input\" name=\"config[{$dbfile}][dbpass]\" id=\"config_{$dbfile}_dbpass\" value=\"".htmlspecialchars_uni($mybb->input['config'][$dbfile]['dbpass'])."\" /></td>
1364				</tr>
1365				<tr class=\"last\">
1366					<td class=\"first\"><label for=\"config_{$dbfile}_dbname\">{$lang->database_name}</label></td>
1367					<td class=\"last alt_col\"><input type=\"text\" class=\"text_input\" name=\"config[{$dbfile}][dbname]\" id=\"config_{$dbfile}_dbname\" value=\"".htmlspecialchars_uni($mybb->input['config'][$dbfile]['dbname'])."\" /></td>
1368				</tr>";
1369		}
1370
1371		// Now we're up to table settings
1372		$db_info[$dbfile] .= "
1373			<tr>
1374				<th colspan=\"2\" class=\"first last\">{$dbtype['title']} {$lang->table_settings}</th>
1375			</tr>
1376			<tr class=\"first\">
1377				<td class=\"first\"><label for=\"config_{$dbfile}_tableprefix\">{$lang->table_prefix}</label></td>
1378				<td class=\"last alt_col\"><input type=\"text\" class=\"text_input\" name=\"config[{$dbfile}][tableprefix]\" id=\"config_{$dbfile}_tableprefix\" value=\"".htmlspecialchars_uni($mybb->input['config'][$dbfile]['tableprefix'])."\" /></td>
1379			</tr>
1380			";
1381
1382		// Encoding selection only if supported
1383		if(is_array($encodings))
1384		{
1385			$select_options = "";
1386			foreach($encodings as $encoding => $title)
1387			{
1388				if($mybb->input['config'][$dbfile]['encoding'] == $encoding)
1389				{
1390					$select_options .= "<option value=\"{$encoding}\" selected=\"selected\">{$title}</option>";
1391				}
1392				else
1393				{
1394					$select_options .= "<option value=\"{$encoding}\">{$title}</option>";
1395				}
1396			}
1397			$db_info[$dbfile] .= "
1398				<tr class=\"last\">
1399					<td class=\"first\"><label for=\"config_{$dbfile}_encoding\">{$lang->table_encoding}</label></td>
1400					<td class=\"last alt_col\"><select name=\"config[{$dbfile}][encoding]\" id=\"config_{$dbfile}_encoding\">{$select_options}</select></td>
1401				</tr>
1402				</tbody>";
1403		}
1404	}
1405	$dbconfig = implode("", $db_info);
1406
1407	echo $lang->sprintf($lang->db_step_config_table, $dbengines, $dbconfig);
1408	$output->print_footer('create_tables');
1409}
1410
1411/**
1412 * Create our tables
1413 */
1414function create_tables()
1415{
1416	global $output, $dbinfo, $errors, $mybb, $dboptions, $lang;
1417
1418	$mybb->input['dbengine'] = $mybb->get_input('dbengine');
1419	if(!file_exists(MYBB_ROOT."inc/db_{$mybb->input['dbengine']}.php"))
1420	{
1421		$errors[] = $lang->db_step_error_invalidengine;
1422		database_info();
1423	}
1424
1425	$mybb->input['config'] = $mybb->get_input('config', MyBB::INPUT_ARRAY);
1426	$config = $mybb->input['config'][$mybb->input['dbengine']];
1427
1428	if(strstr($mybb->input['dbengine'], "sqlite") !== false)
1429	{
1430		if(strstr($config['dbname'], "./") !== false || strstr($config['dbname'], "../") !== false || empty($config['dbname']))
1431		{
1432			$errors[] = $lang->db_step_error_sqlite_invalid_dbname;
1433			database_info();
1434		}
1435	}
1436
1437	// Attempt to connect to the db
1438	require_once MYBB_ROOT."inc/db_{$mybb->input['dbengine']}.php";
1439	switch($mybb->input['dbengine'])
1440	{
1441		case "sqlite":
1442			$db = new DB_SQLite;
1443			break;
1444		case "pgsql":
1445			$db = new DB_PgSQL;
1446			break;
1447		case "pgsql_pdo":
1448			$db = new PostgresPdoDbDriver();
1449			break;
1450		case "mysqli":
1451			$db = new DB_MySQLi;
1452			break;
1453		case "mysql_pdo":
1454			$db = new MysqlPdoDbDriver();
1455			break;
1456		default:
1457			$db = new DB_MySQL;
1458	}
1459 	$db->error_reporting = 0;
1460
1461	if(!isset($config['encoding']))
1462	{
1463		$config['encoding'] = null;
1464	}
1465
1466	$connect_array = array(
1467		"hostname" => $config['dbhost'],
1468		"username" => $config['dbuser'],
1469		"password" => $config['dbpass'],
1470		"database" => $config['dbname'],
1471		"encoding" => $config['encoding']
1472	);
1473
1474	$connection = $db->connect($connect_array);
1475	if($connection === false)
1476	{
1477		$errors[] = $lang->sprintf($lang->db_step_error_noconnect, htmlspecialchars_uni($config['dbhost']));
1478	}
1479	// double check if the DB exists for MySQL
1480	elseif(method_exists($db, 'select_db') && !$db->select_db($config['dbname']))
1481	{
1482		$errors[] = $lang->sprintf($lang->db_step_error_nodbname, htmlspecialchars_uni($config['dbname']));
1483	}
1484
1485	// Most DB engines only allow certain characters in the table name. Oracle requires an alphabetic character first.
1486	if((!preg_match("#^[A-Za-z][A-Za-z0-9_]*$#", $config['tableprefix'])) && $config['tableprefix'] != '')
1487	{
1488		$errors[] = $lang->db_step_error_invalid_tableprefix;
1489	}
1490
1491	// Needs to be smaller then 64 characters total (MySQL Limit).
1492	// This allows 24 characters for the actual table name, which should be sufficient.
1493	if(strlen($config['tableprefix']) > 40)
1494	{
1495		$errors[] = $lang->db_step_error_tableprefix_too_long;
1496	}
1497
1498	if($connection !== false && ($db->engine == 'mysql' || $db->engine == 'mysqli') && $config['encoding'] == 'utf8mb4' && version_compare($db->get_version(), '5.5.3', '<'))
1499	{
1500		$errors[] = $lang->db_step_error_utf8mb4_error;
1501	}
1502
1503	if(is_array($errors))
1504	{
1505		database_info();
1506	}
1507
1508	// Decide if we can use a database encoding or not
1509	if($db->fetch_db_charsets() != false)
1510	{
1511		$db_encoding = "\$config['database']['encoding'] = '".addcslashes($config['encoding'], "'")."';";
1512	}
1513	else
1514	{
1515		$db_encoding = "// \$config['database']['encoding'] = '".addcslashes($config['encoding'], "'")."';";
1516	}
1517
1518	// Write the configuration file
1519	$configdata = "<?php
1520/**
1521 * Database configuration
1522 *
1523 * Please see the MyBB Docs for advanced
1524 * database configuration for larger installations
1525 * https://docs.mybb.com/
1526 */
1527
1528\$config['database']['type'] = '".addcslashes($mybb->input['dbengine'], "'")."';
1529\$config['database']['database'] = '".addcslashes($config['dbname'], "'")."';
1530\$config['database']['table_prefix'] = '".addcslashes($config['tableprefix'], "'")."';
1531
1532\$config['database']['hostname'] = '".addcslashes($config['dbhost'], "'")."';
1533\$config['database']['username'] = '".addcslashes($config['dbuser'], "'")."';
1534\$config['database']['password'] = '".addcslashes($config['dbpass'], "'")."';
1535
1536/**
1537 * Admin CP directory
1538 *  For security reasons, it is recommended you
1539 *  rename your Admin CP directory. You then need
1540 *  to adjust the value below to point to the
1541 *  new directory.
1542 */
1543
1544\$config['admin_dir'] = 'admin';
1545
1546/**
1547 * Hide all Admin CP links
1548 *  If you wish to hide all Admin CP links
1549 *  on the front end of the board after
1550 *  renaming your Admin CP directory, set this
1551 *  to 1.
1552 */
1553
1554\$config['hide_admin_links'] = 0;
1555
1556/**
1557 * Data-cache configuration
1558 *  The data cache is a temporary cache
1559 *  of the most commonly accessed data in MyBB.
1560 *  By default, the database is used to store this data.
1561 *
1562 *  If you wish to use the file system (cache/ directory), MemCache (or MemCached), xcache, APC, APCu, eAccelerator or Redis
1563 *  you can change the value below to 'files', 'memcache', 'memcached', 'xcache', 'apc', 'apcu', 'eaccelerator' or 'redis' from 'db'.
1564 */
1565
1566\$config['cache_store'] = 'db';
1567
1568/**
1569 * Memcache configuration
1570 *  If you are using memcache or memcached as your
1571 *  data-cache, you need to configure the hostname
1572 *  and port of your memcache server below.
1573 *
1574 * If not using memcache, ignore this section.
1575 */
1576
1577\$config['memcache']['host'] = 'localhost';
1578\$config['memcache']['port'] = 11211;
1579
1580/**
1581 * Redis configuration
1582 *  If you are using Redis as your data-cache
1583 *  you need to configure the hostname and port
1584 *  of your redis server below. If you want
1585 *  to connect via unix sockets, use the full
1586 *  path to the unix socket as host and leave
1587 *  the port setting unconfigured or false.
1588 */
1589
1590\$config['redis']['host'] = 'localhost';
1591\$config['redis']['port'] = 6379;
1592
1593/**
1594 * Super Administrators
1595 *  A comma separated list of user IDs who cannot
1596 *  be edited, deleted or banned in the Admin CP.
1597 *  The administrator permissions for these users
1598 *  cannot be altered either.
1599 */
1600
1601\$config['super_admins'] = '1';
1602
1603/**
1604 * Database Encoding
1605 *  If you wish to set an encoding for MyBB uncomment
1606 *  the line below (if it isn't already) and change
1607 *  the current value to the mysql charset:
1608 *  http://dev.mysql.com/doc/refman/5.1/en/charset-mysql.html
1609 */
1610
1611{$db_encoding}
1612
1613/**
1614 * Automatic Log Pruning
1615 *  The MyBB task system can automatically prune
1616 *  various log files created by MyBB.
1617 *  To enable this functionality for the logs below, set the
1618 *  the number of days before each log should be pruned.
1619 *  If you set the value to 0, the logs will not be pruned.
1620 */
1621
1622\$config['log_pruning'] = array(
1623	'admin_logs' => 365, // Administrator logs
1624	'mod_logs' => 365, // Moderator logs
1625	'task_logs' => 30, // Scheduled task logs
1626	'mail_logs' => 180, // Mail error logs
1627	'user_mail_logs' => 180, // User mail logs
1628	'promotion_logs' => 180 // Promotion logs
1629);
1630
1631/**
1632 * Disallowed Remote Hosts
1633 *  List of hosts the fetch_remote_file() function will not
1634 *  perform requests to.
1635 *  It is recommended that you enter hosts resolving to the
1636 *  forum server here to prevent Server Side Request
1637 *  Forgery attacks.
1638 */
1639
1640\$config['disallowed_remote_hosts'] = array(
1641	'localhost',
1642);
1643
1644/**
1645 * Disallowed Remote Addresses
1646 *  List of IPv4 addresses the fetch_remote_file() function
1647 *  will not perform requests to.
1648 *  It is recommended that you enter addresses resolving to
1649 *  the forum server here to prevent Server Side Request
1650 *  Forgery attacks.
1651 *  Removing all values disables resolving hosts in that
1652 *  function.
1653 */
1654
1655\$config['disallowed_remote_addresses'] = array(
1656	'127.0.0.1',
1657	'10.0.0.0/8',
1658	'172.16.0.0/12',
1659	'192.168.0.0/16',
1660);
1661
1662";
1663
1664	$file = fopen(MYBB_ROOT.'inc/config.php', 'w');
1665	fwrite($file, $configdata);
1666	fclose($file);
1667
1668	if(function_exists('opcache_invalidate'))
1669	{
1670		opcache_invalidate(MYBB_ROOT."inc/config.php");
1671	}
1672
1673	// Error reporting back on
1674 	$db->error_reporting = 1;
1675
1676	$output->print_header($lang->table_creation, 'createtables');
1677	echo $lang->sprintf($lang->tablecreate_step_connected, $dboptions[$mybb->input['dbengine']]['short_title'], $db->get_version());
1678
1679	if($dboptions[$mybb->input['dbengine']]['structure_file'])
1680	{
1681		$structure_file = $dboptions[$mybb->input['dbengine']]['structure_file'];
1682	}
1683	else
1684	{
1685		$structure_file = 'mysql_db_tables.php';
1686	}
1687
1688	require_once INSTALL_ROOT."resources/{$structure_file}";
1689	foreach($tables as $val)
1690	{
1691		$val = preg_replace('#mybb_(\S+?)([\s\.,\(]|$)#', $config['tableprefix'].'\\1\\2', $val);
1692		$val = preg_replace('#;$#', $db->build_create_table_collation().";", $val);
1693		preg_match('#CREATE TABLE (\S+)(\s?|\(?)\(#i', $val, $match);
1694		if(!empty($match[1]))
1695		{
1696			$db->drop_table($match[1], false, false);
1697			echo $lang->sprintf($lang->tablecreate_step_created, $match[1]);
1698		}
1699		$db->query($val);
1700		if(!empty($match[1]))
1701		{
1702			echo $lang->done . "<br />\n";
1703		}
1704	}
1705	echo $lang->tablecreate_step_done;
1706	$output->print_footer('populate_tables');
1707}
1708
1709/**
1710 * Insert our default data
1711 */
1712function populate_tables()
1713{
1714	global $output, $lang, $dboptions;
1715
1716	require MYBB_ROOT.'inc/config.php';
1717	$db = db_connection($config);
1718
1719	$output->print_header($lang->table_population, 'tablepopulate');
1720	echo $lang->sprintf($lang->populate_step_insert);
1721
1722	if(!empty($dboptions[$db->type]['population_file']))
1723	{
1724		$population_file = $dboptions[$db->type]['population_file'];
1725	}
1726	else
1727	{
1728		$population_file = 'mysql_db_inserts.php';
1729	}
1730
1731	require_once INSTALL_ROOT."resources/{$population_file}";
1732	foreach($inserts as $val)
1733	{
1734		$val = preg_replace('#mybb_(\S+?)([\s\.,]|$)#', $config['database']['table_prefix'].'\\1\\2', $val);
1735		$db->query($val);
1736	}
1737
1738	// Update the sequences for PgSQL
1739	if($config['database']['type'] == "pgsql")
1740	{
1741		$db->query("SELECT setval('{$config['database']['table_prefix']}attachtypes_atid_seq', (SELECT max(atid) FROM {$config['database']['table_prefix']}attachtypes));");
1742		$db->query("SELECT setval('{$config['database']['table_prefix']}forums_fid_seq', (SELECT max(fid) FROM {$config['database']['table_prefix']}forums));");
1743		$db->query("SELECT setval('{$config['database']['table_prefix']}helpdocs_hid_seq', (SELECT max(hid) FROM {$config['database']['table_prefix']}helpdocs));");
1744		$db->query("SELECT setval('{$config['database']['table_prefix']}helpsections_sid_seq', (SELECT max(sid) FROM {$config['database']['table_prefix']}helpsections));");
1745		$db->query("SELECT setval('{$config['database']['table_prefix']}icons_iid_seq', (SELECT max(iid) FROM {$config['database']['table_prefix']}icons));");
1746		$db->query("SELECT setval('{$config['database']['table_prefix']}profilefields_fid_seq', (SELECT max(fid) FROM {$config['database']['table_prefix']}profilefields));");
1747		$db->query("SELECT setval('{$config['database']['table_prefix']}smilies_sid_seq', (SELECT max(sid) FROM {$config['database']['table_prefix']}smilies));");
1748		$db->query("SELECT setval('{$config['database']['table_prefix']}spiders_sid_seq', (SELECT max(sid) FROM {$config['database']['table_prefix']}spiders));");
1749		$db->query("SELECT setval('{$config['database']['table_prefix']}templategroups_gid_seq', (SELECT max(gid) FROM {$config['database']['table_prefix']}templategroups));");
1750	}
1751
1752	echo $lang->populate_step_inserted;
1753	$output->print_footer('templates');
1754}
1755
1756/**
1757 * Install our theme
1758 */
1759function insert_templates()
1760{
1761	global $mybb, $output, $cache, $db, $lang;
1762
1763	require MYBB_ROOT.'inc/config.php';
1764	$db = db_connection($config);
1765
1766	require_once MYBB_ROOT.'inc/class_datacache.php';
1767	$cache = new datacache;
1768
1769	$output->print_header($lang->theme_installation, 'theme');
1770
1771	echo $lang->theme_step_importing;
1772
1773	$db->delete_query("themes");
1774	$db->delete_query("templates");
1775	$db->delete_query("themestylesheets");
1776	my_rmdir_recursive(MYBB_ROOT."cache/themes", array(MYBB_ROOT."cache/themes/index.html"));
1777
1778	$insert_array = array(
1779		'title' => 'Default Templates'
1780	);
1781	$templateset = $db->insert_query("templatesets", $insert_array);
1782
1783	$contents = @file_get_contents(INSTALL_ROOT.'resources/mybb_theme.xml');
1784	if(!empty($mybb->config['admin_dir']) && file_exists(MYBB_ROOT.$mybb->config['admin_dir']."/inc/functions_themes.php"))
1785	{
1786		require_once MYBB_ROOT.$mybb->config['admin_dir']."/inc/functions.php";
1787		require_once MYBB_ROOT.$mybb->config['admin_dir']."/inc/functions_themes.php";
1788	}
1789	elseif(file_exists(MYBB_ROOT."admin/inc/functions_themes.php"))
1790	{
1791		require_once MYBB_ROOT."admin/inc/functions.php";
1792		require_once MYBB_ROOT."admin/inc/functions_themes.php";
1793	}
1794	else
1795	{
1796		$output->print_error("Please make sure your admin directory is uploaded correctly.");
1797	}
1798	$theme_id = import_theme_xml($contents, array("templateset" => -2, "version_compat" => 1));
1799	$tid = build_new_theme("Default", null, $theme_id);
1800
1801	// Update our properties template set to the correct one
1802	$query = $db->simple_select("themes", "stylesheets, properties", "tid='{$tid}'", array('limit' => 1));
1803
1804	$theme = $db->fetch_array($query);
1805	$properties = my_unserialize($theme['properties']);
1806	$stylesheets = my_unserialize($theme['stylesheets']);
1807
1808	$properties['templateset'] = $templateset;
1809	unset($properties['inherited']['templateset']);
1810
1811	// 1.8: Stylesheet Colors
1812	$contents = @file_get_contents(INSTALL_ROOT.'resources/mybb_theme_colors.xml');
1813
1814	$parser = create_xml_parser($contents);
1815	$tree = $parser->get_tree();
1816
1817	if(is_array($tree) && is_array($tree['colors']))
1818	{
1819		if(is_array($tree['colors']['scheme']))
1820		{
1821			foreach($tree['colors']['scheme'] as $tag => $value)
1822			{
1823				$exp = explode("=", $value['value']);
1824
1825				$properties['colors'][$exp[0]] = $exp[1];
1826			}
1827		}
1828
1829		if(is_array($tree['colors']['stylesheets']))
1830		{
1831			$count = count($properties['disporder']) + 1;
1832			foreach($tree['colors']['stylesheets']['stylesheet'] as $stylesheet)
1833			{
1834				$new_stylesheet = array(
1835					"name" => $db->escape_string($stylesheet['attributes']['name']),
1836					"tid" => $tid,
1837					"attachedto" => $db->escape_string($stylesheet['attributes']['attachedto']),
1838					"stylesheet" => $db->escape_string($stylesheet['value']),
1839					"lastmodified" => TIME_NOW,
1840					"cachefile" => $db->escape_string($stylesheet['attributes']['name'])
1841				);
1842
1843				$sid = $db->insert_query("themestylesheets", $new_stylesheet);
1844				$css_url = "css.php?stylesheet={$sid}";
1845
1846				$cached = cache_stylesheet($tid, $stylesheet['attributes']['name'], $stylesheet['value']);
1847
1848				if($cached)
1849				{
1850					$css_url = $cached;
1851				}
1852
1853				// Add to display and stylesheet list
1854				$properties['disporder'][$stylesheet['attributes']['name']] = $count;
1855				$stylesheets[$stylesheet['attributes']['attachedto']]['global'][] = $css_url;
1856
1857				++$count;
1858			}
1859		}
1860	}
1861
1862	$db->update_query("themes", array("def" => 1, "properties" => $db->escape_string(my_serialize($properties)), "stylesheets" => $db->escape_string(my_serialize($stylesheets))), "tid = '{$tid}'");
1863
1864	echo $lang->theme_step_imported;
1865	$output->print_footer('configuration');
1866}
1867
1868/**
1869 * Default configuration
1870 */
1871function configure()
1872{
1873	global $output, $mybb, $errors, $lang;
1874
1875	$output->print_header($lang->board_config, 'config');
1876
1877	echo <<<EOF
1878		<script type="text/javascript">
1879		function warnUser(inp, warn)
1880		{
1881			var parenttr = $('#'+inp.id).closest('tr');
1882			if(inp.value != inp.defaultValue)
1883			{
1884				if(!parenttr.next('.setting_peeker').length)
1885				{
1886					var revertlink = ' <a href="javascript:revertSetting(\''+inp.defaultValue+'\', \'#'+inp.id+'\');">{$lang->config_step_revert}</a>';
1887					parenttr.removeClass('last').after('<tr class="setting_peeker"><td colspan="2">'+warn+revertlink+'</td></tr>');
1888				}
1889			} else {
1890				parenttr.next('.setting_peeker').remove();
1891				if(parenttr.is(':last-child'))
1892				{
1893					parenttr.addClass('last');
1894				}
1895			}
1896		}
1897
1898		function revertSetting(defval, inpid)
1899		{
1900			$(inpid).val(defval);
1901			var parenttr = $(inpid).closest('tr');
1902			parenttr.next('.setting_peeker').remove();
1903			if(parenttr.is(':last-child'))
1904			{
1905				parenttr.addClass('last');
1906			}
1907		}
1908		</script>
1909
1910EOF;
1911
1912	// If board configuration errors
1913	if(is_array($errors))
1914	{
1915		$error_list = error_list($errors);
1916		echo $lang->sprintf($lang->config_step_error_config, $error_list);
1917
1918		$bbname = htmlspecialchars_uni($mybb->get_input('bbname'));
1919		$bburl = htmlspecialchars_uni($mybb->get_input('bburl'));
1920		$websitename = htmlspecialchars_uni($mybb->get_input('websitename'));
1921		$websiteurl = htmlspecialchars_uni($mybb->get_input('websiteurl'));
1922		$cookiedomain = htmlspecialchars_uni($mybb->get_input('cookiedomain'));
1923		$cookiepath = htmlspecialchars_uni($mybb->get_input('cookiepath'));
1924		$contactemail =  htmlspecialchars_uni($mybb->get_input('contactemail'));
1925	}
1926	else
1927	{
1928		$bbname = 'Forums';
1929		$cookiedomain = '';
1930		$websitename = 'Your Website';
1931
1932		$protocol = "http://";
1933		if((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != "off"))
1934		{
1935			$protocol = "https://";
1936		}
1937
1938		// Attempt auto-detection
1939		if(!empty($_SERVER['HTTP_HOST']))
1940		{
1941			$hostname = $protocol.$_SERVER['HTTP_HOST'];
1942			$cookiedomain = $_SERVER['HTTP_HOST'];
1943		}
1944		elseif(!empty($_SERVER['SERVER_NAME']))
1945		{
1946			$hostname = $protocol.$_SERVER['SERVER_NAME'];
1947			$cookiedomain = $_SERVER['SERVER_NAME'];
1948		}
1949
1950		if(my_substr($cookiedomain, 0, 4) == "www.")
1951		{
1952			$cookiedomain = substr($cookiedomain, 4);
1953		}
1954
1955		// IP addresses and hostnames are not valid
1956		if(my_inet_pton($cookiedomain) !== false || strpos($cookiedomain, '.') === false)
1957		{
1958			$cookiedomain = '';
1959		}
1960		else
1961		{
1962			$cookiedomain = ".{$cookiedomain}";
1963		}
1964
1965		if(!empty($_SERVER['SERVER_PORT']))
1966		{
1967			$port = ":{$_SERVER['SERVER_PORT']}";
1968			$pos = strrpos($cookiedomain, $port);
1969
1970			if($pos !== false)
1971			{
1972				$cookiedomain = substr($cookiedomain, 0, $pos);
1973			}
1974
1975			if($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443 && !preg_match("#:[0-9]#i", $hostname))
1976			{
1977				$hostname .= $port;
1978			}
1979		}
1980
1981		$currentlocation = get_current_location('', '', true);
1982		$noinstall = substr($currentlocation, 0, strrpos($currentlocation, '/install/'));
1983
1984		$cookiepath = $noinstall.'/';
1985		$bburl = $hostname.$noinstall;
1986		$websiteurl = $hostname.'/';
1987
1988		if(isset($_SERVER['SERVER_ADMIN']) && filter_var($_SERVER['SERVER_ADMIN'], FILTER_VALIDATE_EMAIL))
1989		{
1990			$contactemail = $_SERVER['SERVER_ADMIN'];
1991		}
1992		else
1993		{
1994			$contactemail = null;
1995		}
1996	}
1997
1998	echo $lang->sprintf($lang->config_step_table, $bbname, $bburl, $websitename, $websiteurl, $cookiedomain, $cookiepath, $contactemail);
1999	$output->print_footer('adminuser');
2000}
2001
2002/**
2003 * How do we want to name the admin user?
2004 */
2005function create_admin_user()
2006{
2007	global $output, $mybb, $errors, $db, $lang;
2008
2009	$mybb->input['action'] = "adminuser";
2010	// If no errors then check for errors from last step
2011	if(!is_array($errors))
2012	{
2013		if(empty($mybb->input['bburl']))
2014		{
2015			$errors[] = $lang->config_step_error_url;
2016		}
2017		if(empty($mybb->input['bbname']))
2018		{
2019			$errors[] = $lang->config_step_error_name;
2020		}
2021		if(is_array($errors))
2022		{
2023			configure();
2024		}
2025	}
2026	$output->print_header($lang->create_admin, 'admin');
2027
2028	echo <<<EOF
2029		<script type="text/javascript">
2030		function comparePass()
2031		{
2032			var parenttr = $('#adminpass2').closest('tr');
2033			var passval = $('#adminpass2').val();
2034			if(passval && passval != $('#adminpass').val())
2035			{
2036				if(!parenttr.next('.pass_peeker').length)
2037				{
2038					parenttr.removeClass('last').after('<tr class="pass_peeker"><td colspan="2">{$lang->admin_step_nomatch}</td></tr>');
2039				}
2040			} else {
2041				parenttr.addClass('last').next('.pass_peeker').remove();
2042			}
2043		}
2044		</script>
2045
2046EOF;
2047
2048	if(is_array($errors))
2049	{
2050		$error_list = error_list($errors);
2051		echo $lang->sprintf($lang->admin_step_error_config, $error_list);
2052		$adminuser = $mybb->get_input('adminuser');
2053		$adminemail = $mybb->get_input('adminemail');
2054	}
2055	else
2056	{
2057		require MYBB_ROOT.'inc/config.php';
2058		$db = db_connection($config);
2059
2060		echo $lang->admin_step_setupsettings;
2061		$adminuser = $adminemail = '';
2062
2063		$settings = file_get_contents(INSTALL_ROOT.'resources/settings.xml');
2064		$parser = create_xml_parser($settings);
2065		$parser->collapse_dups = 0;
2066		$tree = $parser->get_tree();
2067		$groupcount = $settingcount = 0;
2068
2069		// Insert all the settings
2070		foreach($tree['settings'][0]['settinggroup'] as $settinggroup)
2071		{
2072			$groupdata = array(
2073				'name' => $db->escape_string($settinggroup['attributes']['name']),
2074				'title' => $db->escape_string($settinggroup['attributes']['title']),
2075				'description' => $db->escape_string($settinggroup['attributes']['description']),
2076				'disporder' => (int)$settinggroup['attributes']['disporder'],
2077				'isdefault' => $settinggroup['attributes']['isdefault'],
2078			);
2079			$gid = $db->insert_query('settinggroups', $groupdata);
2080			++$groupcount;
2081			foreach($settinggroup['setting'] as $setting)
2082			{
2083				$settingdata = array(
2084					'name' => $db->escape_string($setting['attributes']['name']),
2085					'title' => $db->escape_string($setting['title'][0]['value']),
2086					'description' => $db->escape_string($setting['description'][0]['value']),
2087					'optionscode' => $db->escape_string($setting['optionscode'][0]['value']),
2088					'value' => $db->escape_string($setting['settingvalue'][0]['value']),
2089					'disporder' => (int)$setting['disporder'][0]['value'],
2090					'gid' => $gid,
2091					'isdefault' => 1
2092				);
2093
2094				$db->insert_query('settings', $settingdata);
2095				$settingcount++;
2096			}
2097		}
2098
2099		if(my_substr($mybb->get_input('bburl'), -1, 1) == '/')
2100		{
2101			$mybb->input['bburl'] = my_substr($mybb->get_input('bburl'), 0, -1);
2102		}
2103
2104		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('bbname'))), "name='bbname'");
2105		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('bburl'))), "name='bburl'");
2106		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('websitename'))), "name='homename'");
2107		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('websiteurl'))), "name='homeurl'");
2108		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('cookiedomain'))), "name='cookiedomain'");
2109		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('cookiepath'))), "name='cookiepath'");
2110		$db->update_query("settings", array('value' => $db->escape_string($mybb->get_input('contactemail'))), "name='adminemail'");
2111		$db->update_query("settings", array('value' => 'contact.php'), "name='contactlink'");
2112
2113		write_settings();
2114
2115		echo $lang->sprintf($lang->admin_step_insertesettings, $settingcount, $groupcount);
2116
2117		// Save the acp pin
2118		$pin = addslashes($mybb->get_input('pin'));
2119
2120		$file = @fopen(MYBB_ROOT."inc/config.php", "a");
2121
2122		@fwrite($file, "/**
2123 * Admin CP Secret PIN
2124 *  If you wish to request a PIN
2125 *  when someone tries to login
2126 *  on your Admin CP, enter it below.
2127 */
2128
2129\$config['secret_pin'] = '{$pin}';");
2130
2131		@fclose($file);
2132
2133		include_once MYBB_ROOT."inc/functions_task.php";
2134		$tasks = file_get_contents(INSTALL_ROOT.'resources/tasks.xml');
2135		$parser = create_xml_parser($tasks);
2136		$parser->collapse_dups = 0;
2137		$tree = $parser->get_tree();
2138		$taskcount = 0;
2139
2140		// Insert scheduled tasks
2141		foreach($tree['tasks'][0]['task'] as $task)
2142		{
2143			$new_task = array(
2144				'title' => $db->escape_string($task['title'][0]['value']),
2145				'description' => $db->escape_string($task['description'][0]['value']),
2146				'file' => $db->escape_string($task['file'][0]['value']),
2147				'minute' => $db->escape_string($task['minute'][0]['value']),
2148				'hour' => $db->escape_string($task['hour'][0]['value']),
2149				'day' => $db->escape_string($task['day'][0]['value']),
2150				'weekday' => $db->escape_string($task['weekday'][0]['value']),
2151				'month' => $db->escape_string($task['month'][0]['value']),
2152				'enabled' => $db->escape_string($task['enabled'][0]['value']),
2153				'logging' => $db->escape_string($task['logging'][0]['value'])
2154			);
2155
2156			$new_task['nextrun'] = fetch_next_run($new_task);
2157
2158			$db->insert_query("tasks", $new_task);
2159			$taskcount++;
2160		}
2161
2162		// For the version check task, set a random date and hour (so all MyBB installs don't query mybb.com all at the same time)
2163		$update_array = array(
2164			'hour' => rand(0, 23),
2165			'weekday' => rand(0, 6)
2166		);
2167
2168		$db->update_query("tasks", $update_array, "file = 'versioncheck'");
2169
2170		echo $lang->sprintf($lang->admin_step_insertedtasks, $taskcount);
2171
2172		$views = file_get_contents(INSTALL_ROOT.'resources/adminviews.xml');
2173		$parser = create_xml_parser($views);
2174		$parser->collapse_dups = 0;
2175		$tree = $parser->get_tree();
2176		$view_count = 0;
2177
2178		// Insert admin views
2179		foreach($tree['adminviews'][0]['view'] as $view)
2180		{
2181			$fields = array();
2182			foreach($view['fields'][0]['field'] as $field)
2183			{
2184				$fields[] = $field['attributes']['name'];
2185			}
2186
2187			$conditions = array();
2188			if(isset($view['conditions'][0]['condition']) && is_array($view['conditions'][0]['condition']))
2189			{
2190				foreach($view['conditions'][0]['condition'] as $condition)
2191				{
2192					if(!$condition['value']) continue;
2193					if($condition['attributes']['is_serialized'] == 1)
2194					{
2195						$condition['value'] = my_unserialize($condition['value']);
2196					}
2197					$conditions[$condition['attributes']['name']] = $condition['value'];
2198				}
2199			}
2200
2201			$custom_profile_fields = array();
2202			if(isset($view['custom_profile_fields'][0]['field']) && is_array($view['custom_profile_fields'][0]['field']))
2203			{
2204				foreach($view['custom_profile_fields'][0]['field'] as $field)
2205				{
2206					$custom_profile_fields[] = $field['attributes']['name'];
2207				}
2208			}
2209
2210			$new_view = array(
2211				"uid" => 0,
2212				"type" => $db->escape_string($view['attributes']['type']),
2213				"visibility" => (int)$view['attributes']['visibility'],
2214				"title" => $db->escape_string($view['title'][0]['value']),
2215				"fields" => $db->escape_string(my_serialize($fields)),
2216				"conditions" => $db->escape_string(my_serialize($conditions)),
2217				"custom_profile_fields" => $db->escape_string(my_serialize($custom_profile_fields)),
2218				"sortby" => $db->escape_string($view['sortby'][0]['value']),
2219				"sortorder" => $db->escape_string($view['sortorder'][0]['value']),
2220				"perpage" => (int)$view['perpage'][0]['value'],
2221				"view_type" => $db->escape_string($view['view_type'][0]['value'])
2222			);
2223			$db->insert_query("adminviews", $new_view);
2224			$view_count++;
2225		}
2226
2227		echo $lang->sprintf($lang->admin_step_insertedviews, $view_count);
2228
2229		echo $lang->admin_step_createadmin;
2230	}
2231
2232	echo $lang->sprintf($lang->admin_step_admintable, $adminuser, $adminemail);
2233	$output->print_footer('final');
2234}
2235
2236/**
2237 * Installation is finished
2238 */
2239function install_done()
2240{
2241	global $output, $db, $mybb, $errors, $cache, $lang;
2242
2243	if(empty($mybb->input['adminuser']))
2244	{
2245		$errors[] = $lang->admin_step_error_nouser;
2246	}
2247	if(empty($mybb->input['adminpass']))
2248	{
2249		$errors[] = $lang->admin_step_error_nopassword;
2250	}
2251	if($mybb->get_input('adminpass') != $mybb->get_input('adminpass2'))
2252	{
2253		$errors[] = $lang->admin_step_error_nomatch;
2254	}
2255	if(empty($mybb->input['adminemail']))
2256	{
2257		$errors[] = $lang->admin_step_error_noemail;
2258	}
2259	if(is_array($errors))
2260	{
2261		create_admin_user();
2262	}
2263
2264	require MYBB_ROOT.'inc/config.php';
2265	$db = db_connection($config);
2266
2267	require MYBB_ROOT.'inc/settings.php';
2268	$mybb->settings = &$settings;
2269
2270	ob_start();
2271	$output->print_header($lang->finish_setup, 'finish');
2272
2273	echo $lang->done_step_usergroupsinserted;
2274
2275	// Insert all of our user groups from the XML file
2276	$usergroup_settings = file_get_contents(INSTALL_ROOT.'resources/usergroups.xml');
2277	$parser = create_xml_parser($usergroup_settings);
2278	$parser->collapse_dups = 0;
2279	$tree = $parser->get_tree();
2280
2281	$admin_gid = '';
2282	$group_count = 0;
2283	foreach($tree['usergroups'][0]['usergroup'] as $usergroup)
2284	{
2285		// usergroup[cancp][0][value]
2286		$new_group = array();
2287		foreach($usergroup as $key => $value)
2288		{
2289			if(!is_array($value))
2290			{
2291				continue;
2292			}
2293
2294			$new_group[$key] = $db->escape_string($value[0]['value']);
2295		}
2296		$db->insert_query("usergroups", $new_group, false);
2297
2298		// If this group can access the admin CP and we haven't established the admin group - set it (just in case we ever change IDs)
2299		if($new_group['cancp'] == 1 && !$admin_gid)
2300		{
2301			$admin_gid = $usergroup['gid'][0]['value'];
2302		}
2303		$group_count++;
2304	}
2305
2306	// Restart usergroup sequence with correct # of groups
2307	if($config['database']['type'] == "pgsql")
2308	{
2309		$db->query("SELECT setval('{$config['database']['table_prefix']}usergroups_gid_seq', (SELECT max(gid) FROM {$config['database']['table_prefix']}usergroups));");
2310	}
2311
2312	echo $lang->done . '</p>';
2313
2314	echo $lang->done_step_admincreated;
2315	$now = TIME_NOW;
2316	$salt = random_str();
2317	$loginkey = generate_loginkey();
2318	$saltedpw = md5(md5($salt).md5($mybb->get_input('adminpass')));
2319
2320	$newuser = array(
2321		'username' => $db->escape_string($mybb->get_input('adminuser')),
2322		'password' => $saltedpw,
2323		'salt' => $salt,
2324		'loginkey' => $loginkey,
2325		'email' => $db->escape_string($mybb->get_input('adminemail')),
2326		'usergroup' => $admin_gid, // assigned above
2327		'regdate' => $now,
2328		'lastactive' => $now,
2329		'lastvisit' => $now,
2330		'website' => '',
2331		'icq' => '',
2332		'skype' =>'',
2333		'google' =>'',
2334		'birthday' => '',
2335		'signature' => '',
2336		'allownotices' => 1,
2337		'hideemail' => 0,
2338		'subscriptionmethod' => '0',
2339		'receivepms' => 1,
2340		'pmnotice' => 1,
2341		'pmnotify' => 1,
2342		'buddyrequestspm' => 1,
2343		'buddyrequestsauto' => 0,
2344		'showimages' => 1,
2345		'showvideos' => 1,
2346		'showsigs' => 1,
2347		'showavatars' => 1,
2348		'showquickreply' => 1,
2349		'invisible' => 0,
2350		'style' => '0',
2351		'timezone' => 0,
2352		'dst' => 0,
2353		'threadmode' => '',
2354		'daysprune' => 0,
2355		'regip' => $db->escape_binary(my_inet_pton(get_ip())),
2356		'language' => '',
2357		'showcodebuttons' => 1,
2358		'tpp' => 0,
2359		'ppp' => 0,
2360		'referrer' => 0,
2361		'buddylist' => '',
2362		'ignorelist' => '',
2363		'pmfolders' => "0**$%%$1**$%%$2**$%%$3**$%%$4**",
2364		'notepad' => '',
2365		'showredirect' => 1,
2366		'usernotes' => ''
2367	);
2368	$db->insert_query('users', $newuser);
2369	echo $lang->done . '</p>';
2370
2371	echo $lang->done_step_adminoptions;
2372	$adminoptions = file_get_contents(INSTALL_ROOT.'resources/adminoptions.xml');
2373	$parser = create_xml_parser($adminoptions);
2374	$parser->collapse_dups = 0;
2375	$tree = $parser->get_tree();
2376	$insertmodule = array();
2377
2378	$db->delete_query("adminoptions");
2379
2380	// Insert all the admin permissions
2381	foreach($tree['adminoptions'][0]['user'] as $users)
2382	{
2383		$uid = $users['attributes']['uid'];
2384
2385		foreach($users['permissions'][0]['module'] as $module)
2386		{
2387			foreach($module['permission'] as $permission)
2388			{
2389				$insertmodule[$module['attributes']['name']][$permission['attributes']['name']] = $permission['value'];
2390			}
2391		}
2392
2393		$defaultviews = array();
2394		foreach($users['defaultviews'][0]['view'] as $view)
2395		{
2396			$defaultviews[$view['attributes']['type']] = $view['value'];
2397		}
2398
2399		$adminoptiondata = array(
2400			'uid' => (int)$uid,
2401			'cpstyle' => '',
2402			'notes' => '',
2403			'permissions' => $db->escape_string(my_serialize($insertmodule)),
2404			'defaultviews' => $db->escape_string(my_serialize($defaultviews))
2405		);
2406
2407		$insertmodule = array();
2408
2409		$db->insert_query('adminoptions', $adminoptiondata);
2410	}
2411	echo $lang->done . '</p>';
2412
2413	// Automatic Login
2414	my_unsetcookie("sid");
2415	my_unsetcookie("mybbuser");
2416	my_setcookie('mybbuser', $uid.'_'.$loginkey, null, true, "lax");
2417	ob_end_flush();
2418
2419	// Make fulltext columns if supported
2420	if($db->supports_fulltext('threads'))
2421	{
2422		$db->create_fulltext_index('threads', 'subject');
2423	}
2424	if($db->supports_fulltext_boolean('posts'))
2425	{
2426		$db->create_fulltext_index('posts', 'message');
2427	}
2428
2429	echo $lang->done_step_cachebuilding;
2430	require_once MYBB_ROOT.'inc/class_datacache.php';
2431	$cache = new datacache;
2432	$cache->update_version();
2433	$cache->update_attachtypes();
2434	$cache->update_smilies();
2435	$cache->update_badwords();
2436	$cache->update_usergroups();
2437	$cache->update_forumpermissions();
2438	$cache->update_stats();
2439	$cache->update_statistics();
2440	$cache->update_forums();
2441	$cache->update_moderators();
2442	$cache->update_usertitles();
2443	$cache->update_reportedcontent();
2444	$cache->update_awaitingactivation();
2445	$cache->update_mycode();
2446	$cache->update_profilefields();
2447	$cache->update_posticons();
2448	$cache->update_spiders();
2449	$cache->update_bannedips();
2450	$cache->update_bannedemails();
2451	$cache->update_birthdays();
2452	$cache->update_groupleaders();
2453	$cache->update_threadprefixes();
2454	$cache->update_forumsdisplay();
2455	$cache->update("plugins", array());
2456	$cache->update("mostonline", array(
2457		'numusers' => 0,
2458		'time' => 0,
2459    ));
2460	$cache->update("internal_settings", array('encryption_key' => random_str(32)));
2461	$cache->update_default_theme();
2462	$cache->update_reportreasons(true);
2463
2464	$version_history = array();
2465	$dh = opendir(INSTALL_ROOT."resources");
2466	while(($file = readdir($dh)) !== false)
2467	{
2468		if(preg_match("#upgrade([0-9]+).php$#i", $file, $match))
2469		{
2470			$version_history[$match[1]] = $match[1];
2471		}
2472	}
2473	sort($version_history, SORT_NUMERIC);
2474	$cache->update("version_history", $version_history);
2475
2476	// Schedule an update check so it occurs an hour ago.  Gotta stay up to date!
2477	$update['nextrun'] = TIME_NOW - 3600;
2478	$db->update_query("tasks", $update, "tid='12'");
2479
2480	$cache->update_update_check();
2481	$cache->update_tasks();
2482
2483	echo $lang->done . '</p>';
2484
2485	echo $lang->done_step_success;
2486
2487	$written = 0;
2488	if(is_writable('./'))
2489	{
2490		$lock = @fopen('./lock', 'w');
2491		$written = @fwrite($lock, '1');
2492		@fclose($lock);
2493		if($written)
2494		{
2495			echo $lang->done_step_locked;
2496		}
2497	}
2498	if(!$written)
2499	{
2500		echo $lang->done_step_dirdelete;
2501	}
2502	echo $lang->done_whats_next;
2503	$output->print_footer('');
2504}
2505
2506/**
2507 * @param array $config
2508 *
2509 * @return DB_MySQL|DB_MySQLi|DB_PgSQL|DB_SQLite|PostgresPdoDbDriver|MysqlPdoDbDriver
2510 */
2511function db_connection($config)
2512{
2513	require_once MYBB_ROOT."inc/db_{$config['database']['type']}.php";
2514	switch($config['database']['type'])
2515	{
2516		case "sqlite":
2517			$db = new DB_SQLite;
2518			break;
2519		case "pgsql":
2520			$db = new DB_PgSQL;
2521			break;
2522		case "pgsql_pdo":
2523			$db = new PostgresPdoDbDriver();
2524			break;
2525		case "mysqli":
2526			$db = new DB_MySQLi;
2527			break;
2528		case "mysql_pdo":
2529			$db = new MysqlPdoDbDriver();
2530			break;
2531		default:
2532			$db = new DB_MySQL;
2533	}
2534
2535	// Connect to Database
2536	define('TABLE_PREFIX', $config['database']['table_prefix']);
2537
2538	$db->connect($config['database']);
2539	$db->set_table_prefix(TABLE_PREFIX);
2540	$db->type = $config['database']['type'];
2541
2542	return $db;
2543}
2544
2545/**
2546 * @param array $array
2547 *
2548 * @return string
2549 */
2550function error_list($array)
2551{
2552	$string = "<ul>\n";
2553	foreach($array as $error)
2554	{
2555		$string .= "<li>{$error}</li>\n";
2556	}
2557	$string .= "</ul>\n";
2558	return $string;
2559}
2560
2561/**
2562 * Write our settings to the settings file
2563 */
2564function write_settings()
2565{
2566	global $db;
2567
2568	$settings = '';
2569	$query = $db->simple_select('settings', '*', '', array('order_by' => 'title'));
2570	while($setting = $db->fetch_array($query))
2571	{
2572		$setting['name'] = addcslashes($setting['name'], "\\'");
2573		$setting['value'] = addcslashes($setting['value'], '\\"$');
2574		$settings .= "\$settings['{$setting['name']}'] = \"{$setting['value']}\";\n";
2575	}
2576	if(!empty($settings))
2577	{
2578		$settings = "<?php\n/*********************************\ \n  DO NOT EDIT THIS FILE, PLEASE USE\n  THE SETTINGS EDITOR\n\*********************************/\n\n{$settings}\n";
2579		$file = fopen(MYBB_ROOT."inc/settings.php", "w");
2580		fwrite($file, $settings);
2581		fclose($file);
2582	}
2583}
2584